text:
import * as Common from '../../../../core/common/common.js';
import * as i18n from '../../../../core/i18n/i18n.js';
import * as Platform from '../../../../core/platform/platform.js';
import * as Formatter from '../../../../models/formatter/formatter.js';
import * as TextUtils from '../../../../models/text_utils/text_utils.js';
import * as CodeMirror from '../../../../third_party/codemirror.next/codemirror.next.js';
import * as CodeHighlighter from '../../../components/code_highlighter/code_highlighter.js';
import * as TextEditor from '../../../components/text_editor/text_editor.js';
import * as UI from '../../legacy.js';

const UIStrings = {
  /**
  *@description Text for the source of something
  */
  source: 'Source',
  /**
  *@description Text to pretty print a file
  */
  prettyPrint: 'Pretty print',
  /**
  *@description Text when something is loading
  */
  loading: 'Loading…',
  /**
  * @description Shown at the bottom of the Sources panel when the user has made multiple
  * simultaneous text selections in the text editor.
  * @example {2} PH1
  */
  dSelectionRegions: '{PH1} selection regions',
  /**
  * @description Position indicator in Source Frame of the Sources panel. The placeholder is a
  * hexadecimal number value, which is why it is prefixed with '0x'.
  * @example {abc} PH1
  */
  bytecodePositionXs: 'Bytecode position `0x`{PH1}',
  /**
  *@description Text in Source Frame of the Sources panel
  *@example {2} PH1
  *@example {2} PH2
  */
  lineSColumnS: 'Line {PH1}, Column {PH2}',
  /**
  *@description Text in Source Frame of the Sources panel
  *@example {2} PH1
  */
  dCharactersSelected: '{PH1} characters selected',
  /**
  *@description Text in Source Frame of the Sources panel
  *@example {2} PH1
  *@example {2} PH2
  */
  dLinesDCharactersSelected: '{PH1} lines, {PH2} characters selected',
};
const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/source_frame/SourceFrame.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);

export interface SourceFrameOptions {
  // Whether to show line numbers. Defaults to true.
  lineNumbers?: boolean;
  // Whether to wrap lines. Defaults to false.
  lineWrapping?: boolean;
}

export const enum Events {
  EditorUpdate = 'EditorUpdate',
  EditorScroll = 'EditorScroll',
}

export type EventTypes = {
  [Events.EditorUpdate]: CodeMirror.ViewUpdate,
  [Events.EditorScroll]: void,
};

export class SourceFrameImpl extends Common.ObjectWrapper.eventMixin<EventTypes, typeof UI.View.SimpleView>(
    UI.View.SimpleView) implements UI.SearchableView.Searchable, UI.SearchableView.Replaceable, Transformer {
  private readonly lazyContent: () => Promise<TextUtils.ContentProvider.DeferredContent>;
  private prettyInternal: boolean;
  private rawContent: string|CodeMirror.Text|null;
  private formattedMap: Formatter.ScriptFormatter.FormatterSourceMapping|null;
  private readonly prettyToggle: UI.Toolbar.ToolbarToggle;
  private shouldAutoPrettyPrint: boolean;
  private readonly progressToolbarItem: UI.Toolbar.ToolbarItem;
  private textEditorInternal: TextEditor.TextEditor.TextEditor;
  // The 'clean' document, before editing
  private baseDoc: CodeMirror.Text;
  private prettyBaseDoc: CodeMirror.Text|null = null;
  private displayedSelection: CodeMirror.EditorSelection|null = null;
  private searchConfig: UI.SearchableView.SearchConfig|null;
  private delayedFindSearchMatches: (() => void)|null;
  private currentSearchResultIndex: number;
  private searchResults: SearchMatch[];
  private searchRegex: UI.SearchableView.SearchRegexResult|null;
  private loadError: boolean;
  private muteChangeEventsForSetContent: boolean;
  private readonly sourcePosition: UI.Toolbar.ToolbarText;
  private searchableView: UI.SearchableView.SearchableView|null;
  private editable: boolean;
  private positionToReveal: {
    line: number,
    column: (number|undefined),
    shouldHighlight: (boolean|undefined),
  }|null;
  private lineToScrollTo: number|null;
  private selectionToSet: TextUtils.TextRange.TextRange|null;
  private loadedInternal: boolean;
  private contentRequested: boolean;
  private wasmDisassemblyInternal: Common.WasmDisassembly.WasmDisassembly|null;
  contentSet: boolean;
  constructor(
      lazyContent: () => Promise<TextUtils.ContentProvider.DeferredContent>,
      private readonly options: SourceFrameOptions = {}) {
    super(i18nString(UIStrings.source));

    this.lazyContent = lazyContent;

    this.prettyInternal = false;
    this.rawContent = null;
    this.formattedMap = null;
    this.prettyToggle = new UI.Toolbar.ToolbarToggle(i18nString(UIStrings.prettyPrint), 'largeicon-pretty-print');
    this.prettyToggle.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, () => {
      void this.setPretty(!this.prettyToggle.toggled());
    });
    this.shouldAutoPrettyPrint = false;
    this.prettyToggle.setVisible(false);

    this.progressToolbarItem = new UI.Toolbar.ToolbarItem(document.createElement('div'));

    this.textEditorInternal = new TextEditor.TextEditor.TextEditor(this.placeholderEditorState(''));
    this.textEditorInternal.style.flexGrow = '1';
    this.element.appendChild(this.textEditorInternal);
    this.element.addEventListener('keydown', (event: KeyboardEvent): void => {
      if (event.defaultPrevented) {
        event.stopPropagation();
      }
    });

    this.baseDoc = this.textEditorInternal.state.doc;

    this.searchConfig = null;
    this.delayedFindSearchMatches = null;
    this.currentSearchResultIndex = -1;
    this.searchResults = [];
    this.searchRegex = null;
    this.loadError = false;

    this.muteChangeEventsForSetContent = false;

    this.sourcePosition = new UI.Toolbar.ToolbarText();

    this.searchableView = null;
    this.editable = false;

    this.positionToReveal = null;
    this.lineToScrollTo = null;
    this.selectionToSet = null;
    this.loadedInternal = false;
    this.contentRequested = false;

    this.wasmDisassemblyInternal = null;
    this.contentSet = false;

    Common.Settings.Settings.instance()
        .moduleSetting('textEditorIndent')
        .addChangeListener(this.#textEditorIndentChanged, this);
  }

  disposeView(): void {
    Common.Settings.Settings.instance()
        .moduleSetting('textEditorIndent')
        .removeChangeListener(this.#textEditorIndentChanged, this);
  }

  async #textEditorIndentChanged(): Promise<void> {
    if (this.prettyInternal) {
      // Indentation settings changed, which are used for pretty printing as well,
      // so if the editor is currently pretty printed, just toggle the state here
      // to apply the new indentation settings.
      await this.setPretty(false);
      await this.setPretty(true);
    }
  }

  private placeholderEditorState(content: string): CodeMirror.EditorState {
    return CodeMirror.EditorState.create({
      doc: content,
      extensions: [
        CodeMirror.EditorState.readOnly.of(true),
        this.options.lineNumbers !== false ? CodeMirror.lineNumbers() : [],
        TextEditor.Config.theme(),
      ],
    });
  }

  protected editorConfiguration(doc: string|CodeMirror.Text): CodeMirror.Extension {
    return [
      CodeMirror.EditorView.updateListener.of(update => this.dispatchEventToListeners(Events.EditorUpdate, update)),
      TextEditor.Config.baseConfiguration(doc),
      TextEditor.Config.closeBrackets,
      TextEditor.Config.sourcesAutocompletion.instance(),
      TextEditor.Config.showWhitespace.instance(),
      TextEditor.Config.allowScrollPastEof.instance(),
      CodeMirror.Prec.lowest(TextEditor.Config.codeFolding.instance()),
      TextEditor.Config.autoDetectIndent.instance(),
      sourceFrameTheme,
      CodeMirror.EditorView.domEventHandlers({
        focus: () => this.onFocus(),
        blur: () => this.onBlur(),
        scroll: () => this.dispatchEventToListeners(Events.EditorScroll),
        contextmenu: event => this.onContextMenu(event),
      }),
      CodeMirror.lineNumbers({
        domEventHandlers:
            {contextmenu: (_view, block, event) => this.onLineGutterContextMenu(block.from, event as MouseEvent)},
      }),
      CodeMirror.EditorView.updateListener.of(
          (update):
              void => {
                if (update.selectionSet || update.docChanged) {
                  this.updateSourcePosition();
                }
                if (update.docChanged) {
                  this.onTextChanged();
                }
              }),
      activeSearchState,
      CodeMirror.Prec.lowest(searchHighlighter),
      config.language.of([]),
      this.wasmDisassemblyInternal ? markNonBreakableLines(this.wasmDisassemblyInternal) : nonBreakableLines,
      this.options.lineWrapping ? CodeMirror.EditorView.lineWrapping : [],
      this.options.lineNumbers !== false ? CodeMirror.lineNumbers() : [],
    ];
  }

  protected onBlur(): void {
  }

  protected onFocus(): void {
    this.resetCurrentSearchResultIndex();
  }

  get wasmDisassembly(): Common.WasmDisassembly.WasmDisassembly|null {
    return this.wasmDisassemblyInternal;
  }

  editorLocationToUILocation(lineNumber: number, columnNumber: number): {
    lineNumber: number,
    columnNumber: number,
  };
  editorLocationToUILocation(lineNumber: number): {
    lineNumber: number,
    columnNumber: number|undefined,
  };
  editorLocationToUILocation(lineNumber: number, columnNumber?: number): {
    lineNumber: number,
    columnNumber?: number|undefined,
  } {
    if (this.wasmDisassemblyInternal) {
      columnNumber = this.wasmDisassemblyInternal.lineNumberToBytecodeOffset(lineNumber);
      lineNumber = 0;
    } else if (this.prettyInternal) {
      [lineNumber, columnNumber] = this.prettyToRawLocation(lineNumber, columnNumber);
    }
    return {lineNumber, columnNumber};
  }

  uiLocationToEditorLocation(lineNumber: number, columnNumber: number|undefined = 0): {
    lineNumber: number,
    columnNumber: number,
  } {
    if (this.wasmDisassemblyInternal) {
      lineNumber = this.wasmDisassemblyInternal.bytecodeOffsetToLineNumber(columnNumber);
      columnNumber = 0;
    } else if (this.prettyInternal) {
      [lineNumber, columnNumber] = this.rawToPrettyLocation(lineNumber, columnNumber);
    }
    return {lineNumber, columnNumber};
  }

  setCanPrettyPrint(canPrettyPrint: boolean, autoPrettyPrint?: boolean): void {
    this.shouldAutoPrettyPrint = canPrettyPrint && Boolean(autoPrettyPrint);
    this.prettyToggle.setVisible(canPrettyPrint);
  }

  setEditable(editable: boolean): void {
    this.editable = editable;
    if (this.loaded && editable !== !this.textEditor.state.readOnly) {
      this.textEditor.dispatch({effects: config.editable.reconfigure(CodeMirror.EditorState.readOnly.of(!editable))});
    }
  }

  private async setPretty(value: boolean): Promise<void> {
    this.prettyInternal = value;
    this.prettyToggle.setEnabled(false);

    const wasLoaded = this.loaded;
    const {textEditor} = this;
    const selection = textEditor.state.selection.main;
    const startPos = textEditor.toLineColumn(selection.from), endPos = textEditor.toLineColumn(selection.to);
    let newSelection;
    if (this.prettyInternal) {
      const content =
          this.rawContent instanceof CodeMirror.Text ? this.rawContent.sliceString(0) : this.rawContent || '';
      const formatInfo = await Formatter.ScriptFormatter.formatScriptContent(this.contentType, content);
      this.formattedMap = formatInfo.formattedMapping;
      await this.setContent(formatInfo.formattedContent);
      this.prettyBaseDoc = textEditor.state.doc;
      const start = this.rawToPrettyLocation(startPos.lineNumber, startPos.columnNumber);
      const end = this.rawToPrettyLocation(endPos.lineNumber, endPos.columnNumber);
      newSelection = textEditor.createSelection(
          {lineNumber: start[0], columnNumber: start[1]}, {lineNumber: end[0], columnNumber: end[1]});
    } else {
      await this.setContent(this.rawContent || '');
      this.baseDoc = textEditor.state.doc;
      const start = this.prettyToRawLocation(startPos.lineNumber, startPos.columnNumber);
      const end = this.prettyToRawLocation(endPos.lineNumber, endPos.columnNumber);
      newSelection = textEditor.createSelection(
          {lineNumber: start[0], columnNumber: start[1]}, {lineNumber: end[0], columnNumber: end[1]});
    }
    if (wasLoaded) {
      textEditor.revealPosition(newSelection, false);
    }
    this.prettyToggle.setEnabled(true);
    this.updatePrettyPrintState();
  }

  // If this is a disassembled WASM file or a pretty-printed file,
  // wire in a line number formatter that shows binary offsets or line
  // numbers in the original source.
  private getLineNumberFormatter(): CodeMirror.Extension {
    if (this.options.lineNumbers === false) {
      return [];
    }
    let formatNumber = null;
    if (this.wasmDisassemblyInternal) {
      const disassembly = this.wasmDisassemblyInternal;
      const lastBytecodeOffset = disassembly.lineNumberToBytecodeOffset(disassembly.lineNumbers - 1);
      const bytecodeOffsetDigits = lastBytecodeOffset.toString(16).length + 1;
      formatNumber = (lineNumber: number): string => {
        const bytecodeOffset =
            disassembly.lineNumberToBytecodeOffset(Math.min(disassembly.lineNumbers, lineNumber) - 1);
        return `0x${bytecodeOffset.toString(16).padStart(bytecodeOffsetDigits, '0')}`;
      };
    } else if (this.prettyInternal) {
      formatNumber = (lineNumber: number): string => {
        const line = this.prettyToRawLocation(lineNumber - 1, 0)[0] + 1;
        if (lineNumber === 1) {
          return String(line);
        }
        if (line !== this.prettyToRawLocation(lineNumber - 2, 0)[0] + 1) {
          return String(line);
        }
        return '-';
      };
    }
    return formatNumber ? CodeMirror.lineNumbers({formatNumber}) : [];
  }

  private updateLineNumberFormatter(): void {
    this.textEditor.dispatch({effects: config.lineNumbers.reconfigure(this.getLineNumberFormatter())});
  }

  private updatePrettyPrintState(): void {
    this.prettyToggle.setToggled(this.prettyInternal);
    this.textEditorInternal.classList.toggle('pretty-printed', this.prettyInternal);
    this.updateLineNumberFormatter();
  }

  private prettyToRawLocation(line: number, column: number|undefined = 0): number[] {
    if (!this.formattedMap) {
      return [line, column];
    }
    return this.formattedMap.formattedToOriginal(line, column);
  }

  private rawToPrettyLocation(line: number, column: number): number[] {
    if (!this.formattedMap) {
      return [line, column];
    }
    return this.formattedMap.originalToFormatted(line, column);
  }

  hasLoadError(): boolean {
    return this.loadError;
  }

  wasShown(): void {
    void this.ensureContentLoaded();
    this.wasShownOrLoaded();
  }

  willHide(): void {
    super.willHide();

    this.clearPositionToReveal();
  }

  async toolbarItems(): Promise<UI.Toolbar.ToolbarItem[]> {
    return [this.prettyToggle, this.sourcePosition, this.progressToolbarItem];
  }

  get loaded(): boolean {
    return this.loadedInternal;
  }

  get textEditor(): TextEditor.TextEditor.TextEditor {
    return this.textEditorInternal;
  }

  get pretty(): boolean {
    return this.prettyInternal;
  }

  get contentType(): string {
    return this.loadError ? '' : this.getContentType();
  }

  protected getContentType(): string {
    return '';
  }

  private async ensureContentLoaded(): Promise<void> {
    if (!this.contentRequested) {
      this.contentRequested = true;

      const progressIndicator = new UI.ProgressIndicator.ProgressIndicator();
      progressIndicator.setTitle(i18nString(UIStrings.loading));
      progressIndicator.setTotalWork(100);
      this.progressToolbarItem.element.appendChild(progressIndicator.element);

      progressIndicator.setWorked(1);

      const deferredContent = await this.lazyContent();
      let error, content;
      if (deferredContent.content === null) {
        error = deferredContent.error;
        this.rawContent = deferredContent.error;
      } else {
        content = deferredContent.content;
        if (deferredContent.isEncoded) {
          const view = new DataView(Common.Base64.decode(deferredContent.content));
          const decoder = new TextDecoder();
          this.rawContent = decoder.decode(view, {stream: true});
        } else if ('wasmDisassemblyInfo' in deferredContent && deferredContent.wasmDisassemblyInfo) {
          const {wasmDisassemblyInfo} = deferredContent;
          this.rawContent = CodeMirror.Text.of(wasmDisassemblyInfo.lines);
          this.wasmDisassemblyInternal = wasmDisassemblyInfo;
        } else {
          this.rawContent = content;
          this.wasmDisassemblyInternal = null;
        }
      }

      // If the input is wasm but v8-based wasm disassembly failed, fall back to wasmparser for backwards compatibility.
      if (content && this.contentType === 'application/wasm' && !this.wasmDisassemblyInternal) {
        const worker = Common.Worker.WorkerWrapper.fromURL(
            new URL('../../../../entrypoints/wasmparser_worker/wasmparser_worker-entrypoint.js', import.meta.url));
        const promise = new Promise<{
          lines: string[],
          offsets: number[],
          functionBodyOffsets: {
            start: number,
            end: number,
          }[],
        }>((resolve, reject) => {
          worker.onmessage =
              // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
              // eslint-disable-next-line @typescript-eslint/no-explicit-any
              ({data}: MessageEvent<any>): void => {
                if ('event' in data) {
                  switch (data.event) {
                    case 'progress':
                      progressIndicator.setWorked(data.params.percentage);
                      break;
                  }
                } else if ('method' in data) {
                  switch (data.method) {
                    case 'disassemble':
                      if ('error' in data) {
                        reject(data.error);
                      } else if ('result' in data) {
                        resolve(data.result);
                      }
                      break;
                  }
                }
              };
          worker.onerror = reject;
        });
        worker.postMessage({method: 'disassemble', params: {content}});
        try {
          const {lines, offsets, functionBodyOffsets} = await promise;
          this.rawContent = content = CodeMirror.Text.of(lines);
          this.wasmDisassemblyInternal =
              new Common.WasmDisassembly.WasmDisassembly(lines, offsets, functionBodyOffsets);
        } catch (e) {
          this.rawContent = content = error = e.message;
        } finally {
          worker.terminate();
        }
      }

      progressIndicator.setWorked(100);
      progressIndicator.done();

      this.formattedMap = null;
      this.prettyToggle.setEnabled(true);

      if (error) {
        this.loadError = true;
        this.textEditor.state = this.placeholderEditorState(error);
        this.prettyToggle.setEnabled(false);
      } else {
        if (this.shouldAutoPrettyPrint && TextUtils.TextUtils.isMinified(content || '')) {
          await this.setPretty(true);
        } else {
          await this.setContent(this.rawContent || '');
        }
      }
      this.contentSet = true;
    }
  }

  revealPosition(position: {lineNumber: number, columnNumber?: number}|number, shouldHighlight?: boolean): void {
    this.lineToScrollTo = null;
    this.selectionToSet = null;
    let line = 0, column = 0;
    if (typeof position === 'number') {
      const {doc} = this.textEditor.state;
      if (position > doc.length) {
        line = doc.lines - 1;
      } else if (position >= 0) {
        const lineObj = doc.lineAt(position);
        line = lineObj.number - 1;
        column = position - lineObj.from;
      }
    } else {
      line = position.lineNumber;
      column = position.columnNumber ?? 0;
    }
    this.positionToReveal = {line, column, shouldHighlight: shouldHighlight};
    this.innerRevealPositionIfNeeded();
  }

  private innerRevealPositionIfNeeded(): void {
    if (!this.positionToReveal) {
      return;
    }

    if (!this.loaded || !this.isShowing()) {
      return;
    }

    const location = this.uiLocationToEditorLocation(this.positionToReveal.line, this.positionToReveal.column);

    const {textEditor} = this;
    textEditor.revealPosition(textEditor.createSelection(location), this.positionToReveal.shouldHighlight);
    this.positionToReveal = null;
  }

  private clearPositionToReveal(): void {
    this.positionToReveal = null;
  }

  scrollToLine(line: number): void {
    this.clearPositionToReveal();
    this.lineToScrollTo = line;
    this.innerScrollToLineIfNeeded();
  }

  private innerScrollToLineIfNeeded(): void {
    if (this.lineToScrollTo !== null) {
      if (this.loaded && this.isShowing()) {
        const {textEditor} = this;
        const position = textEditor.toOffset({lineNumber: this.lineToScrollTo, columnNumber: 0});
        textEditor.dispatch({effects: CodeMirror.EditorView.scrollIntoView(position, {y: 'start', yMargin: 0})});
        this.lineToScrollTo = null;
      }
    }
  }

  setSelection(textRange: TextUtils.TextRange.TextRange): void {
    this.selectionToSet = textRange;
    this.innerSetSelectionIfNeeded();
  }

  private innerSetSelectionIfNeeded(): void {
    const sel = this.selectionToSet;
    if (sel && this.loaded && this.isShowing()) {
      const {textEditor} = this;
      textEditor.dispatch({
        selection: textEditor.createSelection(
            {lineNumber: sel.startLine, columnNumber: sel.startColumn},
            {lineNumber: sel.endLine, columnNumber: sel.endColumn}),
      });
      this.selectionToSet = null;
    }
  }

  private wasShownOrLoaded(): void {
    this.innerRevealPositionIfNeeded();
    this.innerSetSelectionIfNeeded();
    this.innerScrollToLineIfNeeded();
  }

  onTextChanged(): void {
    const wasPretty = this.pretty;
    this.prettyInternal = Boolean(this.prettyBaseDoc && this.textEditor.state.doc.eq(this.prettyBaseDoc));
    if (this.prettyInternal !== wasPretty) {
      this.updatePrettyPrintState();
    }
    this.prettyToggle.setEnabled(this.isClean());

    if (this.searchConfig && this.searchableView) {
      this.performSearch(this.searchConfig, false, false);
    }
  }

  isClean(): boolean {
    return this.textEditor.state.doc.eq(this.baseDoc) ||
        (this.prettyBaseDoc !== null && this.textEditor.state.doc.eq(this.prettyBaseDoc));
  }

  contentCommitted(): void {
    this.baseDoc = this.textEditorInternal.state.doc;
    this.prettyBaseDoc = null;
    this.rawContent = this.textEditor.state.doc.toString();
    this.formattedMap = null;
    if (this.prettyInternal) {
      this.prettyInternal = false;
      this.updatePrettyPrintState();
    }
    this.prettyToggle.setEnabled(true);
  }

  protected async getLanguageSupport(): Promise<CodeMirror.Extension> {
    const languageDesc = await CodeHighlighter.CodeHighlighter.languageFromMIME(this.contentType);
    if (!languageDesc) {
      return [];
    }
    if (this.contentType === 'text/jsx') {
      return [
        languageDesc,
        CodeMirror.javascript.javascriptLanguage.data.of({autocomplete: CodeMirror.completeAnyWord}),
      ];
    }
    return languageDesc;
  }

  async updateLanguageMode(): Promise<void> {
    const langExtension = await this.getLanguageSupport();
    this.textEditor.dispatch({effects: config.language.reconfigure(langExtension)});
  }

  async setContent(content: string|CodeMirror.Text): Promise<void> {
    this.muteChangeEventsForSetContent = true;
    const {textEditor} = this;
    const wasLoaded = this.loadedInternal;
    const scrollTop = textEditor.editor.scrollDOM.scrollTop;
    this.loadedInternal = true;

    const languageSupport = await this.getLanguageSupport();
    const editorState = CodeMirror.EditorState.create({
      doc: content,
      extensions: [
        this.editorConfiguration(content),
        languageSupport,
        config.lineNumbers.of(this.getLineNumberFormatter()),
        config.editable.of(this.editable ? [] : CodeMirror.EditorState.readOnly.of(true)),
      ],
    });
    this.baseDoc = editorState.doc;
    textEditor.state = editorState;
    if (wasLoaded) {
      textEditor.editor.scrollDOM.scrollTop = scrollTop;
    }
    this.wasShownOrLoaded();

    if (this.delayedFindSearchMatches) {
      this.delayedFindSearchMatches();
      this.delayedFindSearchMatches = null;
    }
    this.muteChangeEventsForSetContent = false;
  }

  setSearchableView(view: UI.SearchableView.SearchableView|null): void {
    this.searchableView = view;
  }

  private doFindSearchMatches(
      searchConfig: UI.SearchableView.SearchConfig, shouldJump: boolean, jumpBackwards: boolean): void {
    this.currentSearchResultIndex = -1;

    this.searchRegex = searchConfig.toSearchRegex(true);
    this.searchResults = this.collectRegexMatches(this.searchRegex);

    if (this.searchableView) {
      this.searchableView.updateSearchMatchesCount(this.searchResults.length);
    }

    const editor = this.textEditor;
    if (!this.searchResults.length) {
      if (editor.state.field(activeSearchState)) {
        editor.dispatch({effects: setActiveSearch.of(null)});
      }
    } else if (shouldJump && jumpBackwards) {
      this.jumpToPreviousSearchResult();
    } else if (shouldJump) {
      this.jumpToNextSearchResult();
    } else {
      editor.dispatch({effects: setActiveSearch.of(new ActiveSearch(this.searchRegex, null))});
    }
  }

  performSearch(searchConfig: UI.SearchableView.SearchConfig, shouldJump: boolean, jumpBackwards?: boolean): void {
    if (this.searchableView) {
      this.searchableView.updateSearchMatchesCount(0);
    }

    this.resetSearch();
    this.searchConfig = searchConfig;
    if (this.loaded) {
      this.doFindSearchMatches(searchConfig, shouldJump, Boolean(jumpBackwards));
    } else {
      this.delayedFindSearchMatches =
          this.doFindSearchMatches.bind(this, searchConfig, shouldJump, Boolean(jumpBackwards));
    }

    void this.ensureContentLoaded();
  }

  private resetCurrentSearchResultIndex(): void {
    if (!this.searchResults.length) {
      return;
    }
    this.currentSearchResultIndex = -1;
    if (this.searchableView) {
      this.searchableView.updateCurrentMatchIndex(this.currentSearchResultIndex);
    }
    const editor = this.textEditor;
    const currentActiveSearch = editor.state.field(activeSearchState);
    if (currentActiveSearch && currentActiveSearch.currentRange) {
      editor.dispatch({effects: setActiveSearch.of(new ActiveSearch(currentActiveSearch.regexp, null))});
    }
  }

  private resetSearch(): void {
    this.searchConfig = null;
    this.delayedFindSearchMatches = null;
    this.currentSearchResultIndex = -1;
    this.searchResults = [];
    this.searchRegex = null;
  }

  searchCanceled(): void {
    const range = this.currentSearchResultIndex !== -1 ? this.searchResults[this.currentSearchResultIndex] : null;
    this.resetSearch();
    if (!this.loaded) {
      return;
    }
    const editor = this.textEditor;
    editor.dispatch({
      effects: setActiveSearch.of(null),
      selection: range ? {anchor: range.from, head: range.to} : undefined,
      scrollIntoView: true,
      userEvent: 'select.search.cancel',
    });
  }

  jumpToLastSearchResult(): void {
    this.jumpToSearchResult(this.searchResults.length - 1);
  }

  private searchResultIndexForCurrentSelection(): number {
    return Platform.ArrayUtilities.lowerBound(
        this.searchResults, this.textEditor.state.selection.main, (a, b): number => a.to - b.to);
  }

  jumpToNextSearchResult(): void {
    const currentIndex = this.searchResultIndexForCurrentSelection();
    const nextIndex = this.currentSearchResultIndex === -1 ? currentIndex : currentIndex + 1;
    this.jumpToSearchResult(nextIndex);
  }

  jumpToPreviousSearchResult(): void {
    const currentIndex = this.searchResultIndexForCurrentSelection();
    this.jumpToSearchResult(currentIndex - 1);
  }

  supportsCaseSensitiveSearch(): boolean {
    return true;
  }

  supportsRegexSearch(): boolean {
    return true;
  }

  jumpToSearchResult(index: number): void {
    if (!this.loaded || !this.searchResults.length || !this.searchRegex) {
      return;
    }
    this.currentSearchResultIndex = (index + this.searchResults.length) % this.searchResults.length;
    if (this.searchableView) {
      this.searchableView.updateCurrentMatchIndex(this.currentSearchResultIndex);
    }
    const editor = this.textEditor;
    const range = this.searchResults[this.currentSearchResultIndex];
    editor.dispatch({
      effects: setActiveSearch.of(new ActiveSearch(this.searchRegex, range)),
      selection: {anchor: range.from, head: range.to},
      scrollIntoView: true,
      userEvent: 'select.search',
    });
  }

  replaceSelectionWith(searchConfig: UI.SearchableView.SearchConfig, replacement: string): void {
    const range = this.searchResults[this.currentSearchResultIndex];
    if (!range) {
      return;
    }

    const insert = this.searchRegex?.fromQuery ? range.insertPlaceholders(replacement) : replacement;
    const editor = this.textEditor;
    const changes = editor.state.changes({from: range.from, to: range.to, insert});
    editor.dispatch(
        {changes, selection: {anchor: changes.mapPos(editor.state.selection.main.to, 1)}, userEvent: 'input.replace'});
  }

  replaceAllWith(searchConfig: UI.SearchableView.SearchConfig, replacement: string): void {
    this.resetCurrentSearchResultIndex();

    const regex = searchConfig.toSearchRegex(true);
    const ranges = this.collectRegexMatches(regex);
    if (!ranges.length) {
      return;
    }

    const isRegExp = regex.fromQuery;
    const changes = ranges.map(
        match =>
            ({from: match.from, to: match.to, insert: isRegExp ? match.insertPlaceholders(replacement) : replacement}));

    this.textEditor.dispatch({changes, scrollIntoView: true, userEvent: 'input.replace.all'});
  }

  private collectRegexMatches({regex}: UI.SearchableView.SearchRegexResult): SearchMatch[] {
    const ranges = [];
    let pos = 0;
    for (const line of this.textEditor.state.doc.iterLines()) {
      regex.lastIndex = 0;
      for (;;) {
        const match = regex.exec(line);
        if (!match) {
          break;
        }
        if (match[0].length) {
          const from = pos + match.index;
          ranges.push(new SearchMatch(from, from + match[0].length, match));
        }
      }
      pos += line.length + 1;
    }
    return ranges;
  }

  canEditSource(): boolean {
    return this.editable;
  }

  private updateSourcePosition(): void {
    const {textEditor} = this, {state} = textEditor, {selection} = state;
    if (this.displayedSelection?.eq(selection)) {
      return;
    }
    this.displayedSelection = selection;

    if (selection.ranges.length > 1) {
      this.sourcePosition.setText(i18nString(UIStrings.dSelectionRegions, {PH1: selection.ranges.length}));
      return;
    }
    const {main} = state.selection;
    if (main.empty) {
      const {lineNumber, columnNumber} = textEditor.toLineColumn(main.head);
      const location = this.prettyToRawLocation(lineNumber, columnNumber);
      if (this.wasmDisassemblyInternal) {
        const disassembly = this.wasmDisassemblyInternal;
        const lastBytecodeOffset = disassembly.lineNumberToBytecodeOffset(disassembly.lineNumbers - 1);
        const bytecodeOffsetDigits = lastBytecodeOffset.toString(16).length;
        const bytecodeOffset = disassembly.lineNumberToBytecodeOffset(location[0]);
        this.sourcePosition.setText(i18nString(
            UIStrings.bytecodePositionXs, {PH1: bytecodeOffset.toString(16).padStart(bytecodeOffsetDigits, '0')}));
      } else {
        this.sourcePosition.setText(i18nString(UIStrings.lineSColumnS, {PH1: location[0] + 1, PH2: location[1] + 1}));
      }
    } else {
      const startLine = state.doc.lineAt(main.from), endLine = state.doc.lineAt(main.to);
      if (startLine.number === endLine.number) {
        this.sourcePosition.setText(i18nString(UIStrings.dCharactersSelected, {PH1: main.to - main.from}));
      } else {
        this.sourcePosition.setText(i18nString(
            UIStrings.dLinesDCharactersSelected,
            {PH1: endLine.number - startLine.number + 1, PH2: main.to - main.from}));
      }
    }
  }

  onContextMenu(event: MouseEvent): boolean {
    event.consume(true);  // Consume event now to prevent document from handling the async menu
    const contextMenu = new UI.ContextMenu.ContextMenu(event);
    const {state} = this.textEditor;
    const pos = state.selection.main.from, line = state.doc.lineAt(pos);
    this.populateTextAreaContextMenu(contextMenu, line.number - 1, pos - line.from);
    contextMenu.appendApplicableItems(this);
    void contextMenu.show();
    return true;
  }

  protected populateTextAreaContextMenu(_menu: UI.ContextMenu.ContextMenu, _lineNumber: number, _columnNumber: number):
      void {
  }

  onLineGutterContextMenu(position: number, event: MouseEvent): boolean {
    event.consume(true);  // Consume event now to prevent document from handling the async menu
    const contextMenu = new UI.ContextMenu.ContextMenu(event);
    const lineNumber = this.textEditor.state.doc.lineAt(position).number - 1;
    this.populateLineGutterContextMenu(contextMenu, lineNumber);
    contextMenu.appendApplicableItems(this);
    void contextMenu.show();
    return true;
  }

  protected populateLineGutterContextMenu(_menu: UI.ContextMenu.ContextMenu, _lineNumber: number): void {
  }

  focus(): void {
    this.textEditor.focus();
  }
}

class SearchMatch {
  constructor(readonly from: number, readonly to: number, readonly match: RegExpMatchArray) {
  }

  insertPlaceholders(replacement: string): string {
    return replacement.replace(/\$(\$|&|\d+|<[^>]+>)/g, (_, selector): string => {
      if (selector === '$') {
        return '$';
      }
      if (selector === '&') {
        return this.match[0];
      }
      if (selector[0] === '<') {
        return (this.match.groups && this.match.groups[selector.slice(1, selector.length - 1)]) || '';
      }
      return this.match[Number.parseInt(selector, 10)] || '';
    });
  }
}

export interface Transformer {
  editorLocationToUILocation(lineNumber: number, columnNumber: number): {
    lineNumber: number,
    columnNumber: number,
  };
  editorLocationToUILocation(lineNumber: number): {
    lineNumber: number,
    columnNumber: number|undefined,
  };

  uiLocationToEditorLocation(lineNumber: number, columnNumber?: number): {
    lineNumber: number,
    columnNumber: number,
  };
}

// TODO(crbug.com/1167717): Make this a const enum again
// eslint-disable-next-line rulesdir/const_enum
export enum DecoratorType {
  PERFORMANCE = 'performance',
  MEMORY = 'memory',
  COVERAGE = 'coverage',
}

const config = {
  editable: new CodeMirror.Compartment(),
  language: new CodeMirror.Compartment(),
  lineNumbers: new CodeMirror.Compartment(),
};

class ActiveSearch {
  constructor(
      readonly regexp: UI.SearchableView.SearchRegexResult, readonly currentRange: {from: number, to: number}|null) {
  }

  map(change: CodeMirror.ChangeDesc): ActiveSearch {
    return change.empty || !this.currentRange ?
        this :
        new ActiveSearch(
            this.regexp, {from: change.mapPos(this.currentRange.from), to: change.mapPos(this.currentRange.to)});
  }

  static eq(a: ActiveSearch|null, b: ActiveSearch|null): boolean {
    return Boolean(
        a === b ||
        a && b && a.currentRange?.from === b.currentRange?.from && a.currentRange?.to === b.currentRange?.to &&
            a.regexp.regex.source === b.regexp.regex.source && a.regexp.regex.flags === b.regexp.regex.flags);
  }
}

const setActiveSearch = CodeMirror.StateEffect.define<ActiveSearch|null>(
    {map: (value, mapping): ActiveSearch | null => value && value.map(mapping)});

const activeSearchState = CodeMirror.StateField.define<ActiveSearch|null>({
  create(): null {
    return null;
  },
  update(state, tr): ActiveSearch |
      null {
        return tr.effects.reduce(
            (state, effect) => effect.is(setActiveSearch) ? effect.value : state, state && state.map(tr.changes));
      },
});

const searchMatchDeco = CodeMirror.Decoration.mark({class: 'cm-searchMatch'});
const currentSearchMatchDeco = CodeMirror.Decoration.mark({class: 'cm-searchMatch cm-searchMatch-selected'});

const searchHighlighter = CodeMirror.ViewPlugin.fromClass(class {
  decorations: CodeMirror.DecorationSet;

  constructor(view: CodeMirror.EditorView) {
    this.decorations = this.computeDecorations(view);
  }

  update(update: CodeMirror.ViewUpdate): void {
    const active = update.state.field(activeSearchState);
    if (!ActiveSearch.eq(active, update.startState.field(activeSearchState)) ||
        (active && (update.viewportChanged || update.docChanged))) {
      this.decorations = this.computeDecorations(update.view);
    }
  }

  private computeDecorations(view: CodeMirror.EditorView): CodeMirror.DecorationSet {
    const active = view.state.field(activeSearchState);
    if (!active) {
      return CodeMirror.Decoration.none;
    }

    const builder = new CodeMirror.RangeSetBuilder<CodeMirror.Decoration>();
    const {doc} = view.state;
    for (const {from, to} of view.visibleRanges) {
      let pos = from;
      for (const part of doc.iterRange(from, to)) {
        if (part !== '\n') {
          active.regexp.regex.lastIndex = 0;
          for (;;) {
            const match = active.regexp.regex.exec(part);
            if (!match) {
              break;
            }
            const start = pos + match.index, end = start + match[0].length;
            const current = active.currentRange && active.currentRange.from === start && active.currentRange.to === end;
            builder.add(start, end, current ? currentSearchMatchDeco : searchMatchDeco);
          }
        }
        pos += part.length;
      }
    }
    return builder.finish();
  }
}, {decorations: (value): CodeMirror.DecorationSet => value.decorations});

const nonBreakableLineMark = new (class extends CodeMirror.GutterMarker {
  elementClass = 'cm-nonBreakableLine';
})();

// Effect to add lines (by position) to the set of non-breakable lines.
export const addNonBreakableLines = CodeMirror.StateEffect.define<readonly number[]>();

const nonBreakableLines = CodeMirror.StateField.define<CodeMirror.RangeSet<CodeMirror.GutterMarker>>({
  create(): CodeMirror.RangeSet<CodeMirror.GutterMarker> {
    return CodeMirror.RangeSet.empty;
  },
  update(deco, tr): CodeMirror.RangeSet<CodeMirror.GutterMarker> {
    return tr.effects.reduce((deco, effect) => {
      return !effect.is(addNonBreakableLines) ?
          deco :
          deco.update({add: effect.value.map(pos => nonBreakableLineMark.range(pos))});
    }, deco.map(tr.changes));
  },
  provide: field => CodeMirror.lineNumberMarkers.from(field),
});

export function isBreakableLine(state: CodeMirror.EditorState, line: CodeMirror.Line): boolean {
  const nonBreakable = state.field(nonBreakableLines);
  if (!nonBreakable.size) {
    return true;
  }
  let found = false;
  nonBreakable.between(line.from, line.from, () => {
    found = true;
  });
  return !found;
}

function markNonBreakableLines(disassembly: Common.WasmDisassembly.WasmDisassembly): CodeMirror.Extension {
  // Mark non-breakable lines in the Wasm disassembly after setting
  // up the content for the text editor (which creates the gutter).
  return nonBreakableLines.init(state => {
    const marks = [];
    for (const lineNumber of disassembly.nonBreakableLineNumbers()) {
      if (lineNumber < state.doc.lines) {
        marks.push(nonBreakableLineMark.range(state.doc.line(lineNumber + 1).from));
      }
    }
    return CodeMirror.RangeSet.of(marks);
  });
}

const sourceFrameTheme = CodeMirror.EditorView.theme({
  '&.cm-editor': {height: '100%'},
  '.cm-scroller': {overflow: 'auto'},
  '.cm-lineNumbers .cm-gutterElement.cm-nonBreakableLine': {color: 'var(--color-non-breakable-line) !important'},
  '.cm-searchMatch': {
    border: '1px solid var(--color-search-match-border)',
    borderRadius: '3px',
    margin: '0 -1px',
    '&.cm-searchMatch-selected': {
      borderRadius: '1px',
      backgroundColor: 'var(--color-selected-search-match-background)',
      borderColor: 'var(--color-selected-search-match-background)',
      '&, & *': {
        color: 'var(--color-selected-search-match) !important',
      },
    },
  },
  ':host-context(.pretty-printed) & .cm-lineNumbers .cm-gutterElement': {
    color: 'var(--color-primary)',
  },
});


text:
trait Trait {
    #[inline] //~ WARN `#[inline]` is ignored on constants
    //~^ WARN this was previously accepted
    const X: u32;

    #[inline] //~ ERROR attribute should be applied to function or closure
    type T;

    type U;
}

impl Trait for () {
    #[inline] //~ WARN `#[inline]` is ignored on constants
    //~^ WARN this was previously accepted
    const X: u32 = 0;

    #[inline] //~ ERROR attribute should be applied to function or closure
    type T = Self;

    #[inline] //~ ERROR attribute should be applied to function or closure
    type U = impl Trait; //~ ERROR could not find defining uses
}

extern "C" {
    #[inline] //~ ERROR attribute should be applied to function or closure
    static X: u32;

    #[inline] //~ ERROR attribute should be applied to function or closure
    type T;
}

fn main() {}

redpajama_set_name: RedPajamaGithub


text:
package nest.sparkle.loader

import java.nio.ByteBuffer
import scala.reflect.runtime.universe._
import spray.json.JsValue
import nest.sparkle.util.{GenericFlags, StringUtil}

/** support for parsing text column headers with ascribed types e.g. myColumn:Int */
object TypedColumnHeader {
  /** pattern match support for identifying the ascribed type of a column */
  def unapply(column: String): Option[TypeTag[_]] = {
    suffix(column) match {
      case Some("boolean") => Some(typeTag[Boolean])
      case Some("bool")    => Some(typeTag[Boolean])
      case Some("short")   => Some(typeTag[Short])
      case Some("int")     => Some(typeTag[Int])
      case Some("long")    => Some(typeTag[Long])
      case Some("double")  => Some(typeTag[Double])
      case Some("char")    => Some(typeTag[Char])
      case Some("string")  => Some(typeTag[String])
      case Some("json")    => Some(typeTag[JsValue])
      case Some("flags")   => Some(typeTag[GenericFlags])
      case Some("blob")    => Some(typeTag[ByteBuffer])
      case _               => None
    }
  }

  /** return the column header without the type ascription e.g. "myColumn:Int" => "myColumn" */
  def withoutSuffix(column: String): String = {
    suffix(column) match {
      case Some(suffix) =>
        val suffixLength = ":".length + suffix.length
        column.take(column.length - suffixLength)
      case _ =>
        column
    }
  }

  /** return the :suffix of a string "myColumn:Int" => "Int" */
  private def suffix(column: String): Option[String] = {
    StringUtil.findSuffix(column.toLowerCase, ":")
  }
}


text:
/*
 * 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.facebook.presto.operator.scalar;

import com.facebook.presto.operator.Description;
import com.facebook.presto.spi.PageBuilder;
import com.facebook.presto.spi.block.Block;
import com.facebook.presto.spi.block.BlockBuilder;
import com.facebook.presto.spi.type.Type;
import com.facebook.presto.type.SqlType;
import com.google.common.collect.ImmutableList;

@ScalarFunction("concat")
@Description("Concatenates given arrays")
public final class ArrayConcatFunction
{
    private final PageBuilder pageBuilder;

    @TypeParameter("E")
    public ArrayConcatFunction(@TypeParameter("E") Type elementType)
    {
        pageBuilder = new PageBuilder(ImmutableList.of(elementType));
    }

    @TypeParameter("E")
    @SqlType("array(E)")
    public Block concat(@TypeParameter("E") Type elementType, @SqlType("array(E)") Block leftBlock, @SqlType("array(E)") Block rightBlock)
    {
        if (leftBlock.getPositionCount() == 0) {
            return rightBlock;
        }
        if (rightBlock.getPositionCount() == 0) {
            return leftBlock;
        }

        if (pageBuilder.isFull()) {
            pageBuilder.reset();
        }

        BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0);
        for (int i = 0; i < leftBlock.getPositionCount(); i++) {
            elementType.appendTo(leftBlock, i, blockBuilder);
        }
        for (int i = 0; i < rightBlock.getPositionCount(); i++) {
            elementType.appendTo(rightBlock, i, blockBuilder);
        }
        int total = leftBlock.getPositionCount() + rightBlock.getPositionCount();
        pageBuilder.declarePositions(total);
        return blockBuilder.getRegion(blockBuilder.getPositionCount() - total, total);
    }
}


text:
/**
*============================================================================
*  The Ohio State University Research Foundation, The University of Chicago -
*  Argonne National Laboratory, Emory University, SemanticBits LLC,
*  and Ekagra Software Technologies Ltd.
*
*  Distributed under the OSI-approved BSD 3-Clause License.
*  See http://ncip.github.com/cagrid-workflow/LICENSE.txt for details.
*============================================================================
**/
package net.sf.taverna.wsdl.soap;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.HashMap;
import java.util.Map;

import net.sf.taverna.wsdl.parser.WSDLParser;
import net.sf.taverna.wsdl.testutils.LocationConstants;

import org.apache.axis.message.SOAPBodyElement;
import org.junit.Test;
import org.w3c.dom.Node;

public class LiteralBodyBuilderTest implements LocationConstants{

	@Test
	public void testUnqualifiedNamespaces() throws Exception {
		BodyBuilder builder = createBuilder(WSDL_TEST_BASE+"whatizit.wsdl", "queryPmid");

		assertTrue("Is is the wrong type, it should be LiteralBodyBuilder",builder instanceof LiteralBodyBuilder);

		String parameters = "<parameters xmlns=\"http://www.ebi.ac.uk/webservices/whatizit/ws\"><pipelineName xmlns=\"\">swissProt</pipelineName><pmid xmlns=\"\">1234</pmid></parameters>";
		Map<String,Object> inputMap = new HashMap<String, Object>();
		inputMap.put("parameters", parameters);

		SOAPBodyElement body = builder.build(inputMap);

		String xml = body.getAsString();

		assertTrue("Content of body is incorrect in the definition of the pipelineName and pmid:"+xml,xml.contains("<pipelineName xmlns=\"\">swissProt</pipelineName><pmid xmlns=\"\">1234</pmid>"));
		assertTrue("Wrapping element should have its namespace declared",xml.contains("<ns1:queryPmid"));
	}

	@Test
	public void testQualifiedUnwrapped() throws Exception {
		BodyBuilder builder = createBuilder(WSDL_TEST_BASE+"TestServices-unwrapped.wsdl", "countString");

		assertTrue("Is is the wrong type, it should be LiteralBodyBuilder",builder instanceof LiteralBodyBuilder);
		Map<String,Object>inputMap = new HashMap<String, Object>();
		inputMap.put("str", "bob");

		String xml = builder.build(inputMap).getAsString();

		assertEquals("XML should containe qualifed namespace for str",xml,"<ns1:str xmlns:ns1=\"http://testing.org\">bob</ns1:str>");
	}

	@Test
	public void testUnwrappedSimple() throws Exception {
		BodyBuilder builder = createBuilder(WSDL_TEST_BASE+"TestServices-unwrapped.wsdl", "countString");

		assertTrue("Wrong type of builder, it should be Literal based",builder instanceof LiteralBodyBuilder);

		Map<String,Object> inputMap = new HashMap<String, Object>();
		inputMap.put("str", "12345");

		SOAPBodyElement body = builder.build(inputMap);

		assertEquals("Input element should be named str:","str",body.getNodeName());
		assertEquals("Value should be 12345:","12345",body.getFirstChild().getNextSibling().getNodeValue());
	}

	@Test
	public void testUnwrappedArray() throws Exception {
		BodyBuilder builder = createBuilder(WSDL_TEST_BASE+"TestServices-unwrapped.wsdl", "countStringArray");

		assertTrue("Wrong type of builder, it should be Literal based",builder instanceof LiteralBodyBuilder);

		Map<String,Object> inputMap = new HashMap<String, Object>();
		inputMap.put("array", "<array><item>1</item><item>2</item><item>3</item></array>");

		SOAPBodyElement body = builder.build(inputMap);

		String xml = body.getAsString();
		assertEquals("Outer element should be named array. xml = "+xml,"array",body.getNodeName());

		Node itemElement = body.getFirstChild().getNextSibling();
		assertEquals("Array element should be named item. xml = "+xml,"item",itemElement.getNodeName());
		assertEquals("First Array element should have the value '1'. xml = "+xml,"1",itemElement.getFirstChild().getNodeValue());
	}

	@Test
	public void testRPCLiteral() throws Exception {
		BodyBuilder builder = createBuilder(WSDL_TEST_BASE+"MyService-rpc-literal.wsdl", "countString");

		assertTrue("Wrong type of builder, it should be Literal based",builder instanceof LiteralBodyBuilder);

		Map<String,Object> inputMap = new HashMap<String, Object>();
		inputMap.put("str", "abcdef");

		SOAPBodyElement body = builder.build(inputMap);

		assertEquals("Outer element should be named countString","countString",body.getNodeName());
		Node strNode = body.getFirstChild();
		assertEquals("Inner element should be called 'str'","str",strNode.getNodeName());
		assertEquals("str content should be abcdef","abcdef",strNode.getFirstChild().getNextSibling().getNodeValue());
	}

	protected BodyBuilder createBuilder(String wsdl, String operation) throws Exception {
		WSDLParser parser = new WSDLParser(wsdl);
		return BodyBuilderFactory.instance().create(parser, operation, parser.getOperationInputParameters(operation));
	}
}


text:
package es.upm.oeg.lab.data.upf;

/**
 * Created by cbadenes on 26/10/15.
 */

import lombok.Builder;
import lombok.Getter;
import lombok.Singular;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Builder
@Getter
public class Criteria{
    private boolean fullText            = false;
    private boolean abstracts           = false;
    private boolean centroidSummary     = false;
    private boolean titleSummary        = false;
    private boolean outcome             = false;
    private boolean futureWork          = false;
    private boolean approach            = false;
    private boolean background          = false;
    private boolean challenge           = false;
    private boolean terms               = false;
    private boolean introduction        = false;
    private boolean conclusion          = false;

    @Singular
    private Set<String> sections;

    public List<String> enabled(){
        List<String> values = new ArrayList<>();
        if (fullText)           values.add("full");
        if (abstracts)          values.add("abstract");
        if (centroidSummary)    values.add("csummary");
        if (titleSummary)       values.add("tsummary");
        if (outcome)            values.add("outcome");
        if (futureWork)         values.add("fwork");
        if (approach)           values.add("approach");
        if (background)         values.add("background");
        if (challenge)          values.add("challenge");
        if (terms)              values.add("terms");
        if (introduction)       values.add("introduction");
        if (conclusion)         values.add("conclusion");
        return values;
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/recipeitem_detail_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:overScrollMode="never" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >

            <ImageView
                android:id="@+id/recipe_image"
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:scaleType="centerCrop" />

            <TextView
                android:id="@+id/recipe_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="@dimen/recipe_name_padding"
                android:text="Manja name goes here"
                android:textAppearance="?android:attr/textAppearanceLarge" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <LinearLayout
                    android:id="@+id/recipe_prep_time_layout"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical" >

                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="30dp"
                        android:src="@drawable/icon_watch" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:text="@string/prep"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#99333333"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/recipe_prep_time"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:text="10 min."
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#333333" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/recipe_cook_time_layout"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical" >

                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="30dp"
                        android:src="@drawable/icon_watch" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:text="@string/cook"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#99333333"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/recipe_cook_time"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:text="15 min."
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#333333" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/recipe_total_time_layout"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical" >

                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="30dp"
                        android:src="@drawable/icon_clock" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:text="@string/total"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#99333333"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/recipe_total_time"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:text="25 min."
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#333333" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/recipe_servings_layout"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical" >

                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="30dp"
                        android:src="@drawable/icon_person" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:text="@string/serves"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#99333333"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/recipe_serves"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:text="4"
                        android:textAppearance="?android:attr/textAppearanceSmall"
                        android:textColor="#333333" />
                </LinearLayout>
            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginBottom="@dimen/vertical_padding"
                android:layout_marginLeft="@dimen/horizontal_padding"
                android:layout_marginRight="@dimen/horizontal_padding"
                android:layout_marginTop="@dimen/vertical_padding"
                android:background="#99333333" />

            <LinearLayout
                android:id="@+id/recipe_summary_layout"
                style="@style/ContentGroupContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >

                <TextView
                    style="@style/ContentGroupTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/summary" />

                <TextView
                    android:id="@+id/recipe_summary"
                    style="@style/ContentGroupContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="summary text" />
            </LinearLayout>

            <LinearLayout
                android:id="@+id/recipe_ingredients_layout"
                style="@style/ContentGroupContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >

                <TextView
                    style="@style/ContentGroupTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/ingredients" />

                <TextView
                    android:id="@+id/recipe_ingredients"
                    style="@style/ContentGroupContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="ingredients text" />
            </LinearLayout>

            <LinearLayout
                android:id="@+id/recipe_directions_layout"
                style="@style/ContentGroupContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >

                <TextView
                    style="@style/ContentGroupTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/directions" />

                <TextView
                    android:id="@+id/recipe_directions"
                    style="@style/ContentGroupContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="directions text" />
            </LinearLayout>
        </LinearLayout>
    </ScrollView>

</LinearLayout>


text:
Canvas2D.Position = Class.extend( {
    init: function( shape, left, top ) {
	this.shape = shape;
	this.left  = left || null;
	this.top   = top  || null;
    },

    toADL: function(prefix) {
	var loc = "";
	if( this.left != null && this.top != null ) {
	    loc = prefix + "[@" + this.left + "," + this.top + "]\n";
	}
	return loc + this.shape.toADL(prefix);
    },

    getLeft: function() { return this.left; },
    getTop : function() { return this.top;  },

    getWidth : function() { return this.shape.getWidth();  },
    getHeight: function() { return this.shape.getHeight(); },

    getCenter: function() {
	var center = this.shape.getCenter();
	center.left += this.left;
	center.top += this.top;
	return center;
    },

    getBox: function() {
	return { left  : this.left,
		 right : this.left + this.shape.getWidth(),
		 top   : this.top,
		 bottom: this.top  + this.shape.getHeight() };
    },

    getPort: function(port) {
	var port = this.shape.getPort(port);
	port.left += this.left;
	port.top  += this.top;
	return port;
    },

    render: function( sheet ) {
	this.shape.render( sheet, this.left, this.top );
    },

    move: function( dleft, dtop ) {
	this.left += dleft;
	this.top  += dtop;
	this.fireEvent( "change",
			"from " + this.left - dleft + "," + this.top - dtop +
			" to " + this.left + "," + this.top );
    },

    getName: function() {
	return this.shape.getName();
    },

    hit: function(x,y) {
	var rx = x - this.left;
	var ry = y - this.top;
	if( rx < 0 || ry < 0 ) { return false; }
	return this.shape.hit(rx, ry);
    },

    hitArea: function(left, top, right, bottom) {
	var rleft   = left   - this.left;
	var rtop    = top    - this.top;
	var rright  = right  - this.left;
	var rbottom = bottom - this.top;
	return this.shape.hitArea(min(rleft,rright),
				  min(rtop,rbottom),
				  max(rleft,rright),
				  max(rtop,rbottom));

    },

    delayRender: function() {
	return this.shape.delayRender();
    }
});

ProtoJS.mix( Canvas2D.Factory.extensions.all.EventHandling,
	     Canvas2D.Position.prototype );


text:
@echo off
color 0A
title Demo 1
goto start

:notstart
echo This is the last page to display.
pause
cls
goto multiline

:start
echo This page will display first since it is called first.
pause
cls
goto notstart

:multiline
echo This is line 1.
echo This is line 2.
echo line 3.
pause


text:
Chi siamo?

L'Associazione Rete Famiglie Adottive nasce in Umbria da un gruppo di famiglie che si sono conosciute
frequentando i corsi post-adozione e organizzando le "Feste delle famiglie adottive",
che hanno coltivato la relazione con il territorio e si sono riconosciute nell'importanza
di condividere il proprio vissuto e porsi come "compagnia" e come risorsa tra sé e altre famiglie.

La parola "rete" rimanda alle famiglie come nodi autonomi ma interconnessi,
nodi che sono molto diversi tra loro ma condividono lo stesso scopo,
nodi che comunicano e si aiutano tra loro
parlando lo stesso linguaggio stabilito insieme, e quando un nodo
ha un problema gli altri se ne fanno carico, nodi che hanno memoria di quello
che è accaduto e ne fanno tesoro, un intreccio di strade in cui si trova sempre
il percorso migliore o la risorsa giusta per proseguire.


text:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <list>
#include <cmath>
#include <map>

typedef struct CvWSNode
{
    struct CvWSNode* next;
    int mask_ofs;
    int img_ofs;
}
CvWSNode;

typedef struct CvWSQueue
{
    CvWSNode* first;
    CvWSNode* last;
}
CvWSQueue;

using namespace cv;
using namespace std;

// GLOBAL VARS

// images
Mat markerMask; // image that contains the seeds
Mat imgOneChannel; // this image is used to mark in the markerMask image the exterior and forbidden areas as a segmented area
Mat expandedPolygonImage; // extended image with white borders
Mat wshed; // image with the final segmentation

// polygon vectors
vector< vector<cv::Point2d> > utm_polygon; // the polygon that comes from the utm coordinates
vector< vector<cv::Point> > cpp_polygon; // the resultant polygon that comes from translating utm to euclidean coordinates
vector< vector<cv::Point> > scaled_polygon; // the cpp_polygon scaled to be draw in a bigger image
vector< vector<cv::Point> > viewport_polygon; // the cpp_polygon scaled to be draw in a bigger image

// max/min values for distance to centroid calculation
double max_x = std::numeric_limits<double>::min();
double max_y = std::numeric_limits<double>::min();
double min_x = std::numeric_limits<double>::max();
double min_y = std::numeric_limits<double>::max();

string polygonFilePath = "/home/jorge/Desktop/polygon.txt";
string input_img_filename;
string output_img_filename;

// output image info
int width, height, final_w, final_h, desired_width = 500, added_lines = 20;
double scale_ratio = 1;

static CvWSNode* icvAllocWSNodes( CvMemStorage* storage );
void watershed2( InputArray _src, InputOutputArray markers, int* percentages, int* conqueredCells, int numberOfCells );
void cvWatershed2( const CvArr* srcarr, CvArr* dstarr, int* percentages, int* conqueredCells, int numberOfCells );
Mat createMatImg(int numberOfSeeds);
std::list<cv::Point> generate_seed_points(int numberOfSeeds);
void save_contours_to_disk(vector<vector<Point> > *color_contours, int size, int* percentages);
void save_images_to_disk();
void save_config_to_disk();

int main( int argc, char** argv )
{

    if(argc < 3)
    {
        cout << "Usage: area_partition polygon_file.txt percentage1 [percentage2] [percentage3] ... [percentageN]" << endl;
        return -1;

    }

    int numberOfSeeds = argc - 2;
    int percentages[numberOfSeeds], conqueredCells[numberOfSeeds], total_percentage = 0;
    polygonFilePath = string(argv[1]);
    for(int i=0; i<numberOfSeeds; i++)
    {
        conqueredCells[i] = 0;
        int perct = atoi(argv[i+2]);
        percentages[i] = perct;
        total_percentage += perct;

    }

    if(total_percentage < 100)
    {
        cout << "Warning: the sum of percentages is lower than 100. Some parts of the polygon won't be segmented." << endl;

    }
    else if(total_percentage > 100)
    {
        cout << "Error: the sum of percentages is greater than 100. Aborting..." << endl;
        return -1;

    }

    // create the img path names
    string filename1 = polygonFilePath.substr(0, polygonFilePath.size()-4); // avoid the .txt chars
    string filename2 = polygonFilePath.substr(0, polygonFilePath.size()-4); // avoid the .txt chars
    input_img_filename = filename1.append("_input_image.png");
    output_img_filename = filename2.append("_output_image.png");

    // The following Mat contains the polygon painted inside. Some of his vertex will touch the image border.
    // Due to the fact that some OpenCV functions such as findContours don't take into account the 1 pixel border of
    // the image, that polygon image must be repainted inside a bigger one to avoid loosing some vertex.
    // The polygon is painted in black while the background (exterior and forbidden areas) is white.
    Mat img0 = createMatImg(numberOfSeeds);
    if( img0.empty() )
    {
        cout << "Unable to create polygon image from path '" << string(polygonFilePath) <<  "'. Aborting..." << endl;
        cout << "Check that the number of seeds is equal or less than the number of vertex." << endl;
        return -1;

    }

    // The following image is the bigger one that contains the polygon image inside. The background is white.
    // Also the additional rows and cols will be white.
    expandedPolygonImage = Mat(img0.rows + added_lines, img0.cols + added_lines, CV_8UC3);
    expandedPolygonImage = Scalar::all(255);

    // To paint the polygon image in the bigger one, we create a ROI with appropriate height and width.
    // An offset of added_lines/2 is applied to center the ROI.
    cv::Rect roi( cv::Point(added_lines/2, added_lines/2), cv::Size(img0.cols, img0.rows));
    cv::Mat destinationROI = expandedPolygonImage(roi);
    img0.copyTo( destinationROI );

    // The watershed algorithm paints in white the barriers between segmented areas. If we use the vertex to place
    // the seeds, then we need an additional border for the polygon to let the algorithm create a barrier between the
    // polygon itself and the outter white background.
    // Thickness may be a problem if the additional pixels are added inner to the contour.
    drawContours( expandedPolygonImage, viewport_polygon, 0, Scalar(0, 0, 0), 2);
    cvtColor(expandedPolygonImage, markerMask, COLOR_BGR2GRAY); // markerMask is a 1-channel image
    cvtColor(expandedPolygonImage, imgOneChannel, COLOR_BGR2GRAY);
    markerMask = Scalar::all(0);

    // Generate and place the seed points
    std::list<cv::Point> seed_points = generate_seed_points(numberOfSeeds);
    std::list<cv::Point>::iterator it;
    for (it=seed_points.begin(); it!=seed_points.end(); ++it)
    {
        cv::Point seed = (*it);
        markerMask.at<uchar>(seed) = 255;

    }

    // Start of the watershed algorithm
    int i, j, compCount = 0;
    vector<vector<cv::Point> > contours;
    vector<Vec4i> hierarchy;
    // Find the seeds, pixels with value = 255. Each contour is a vector of points
    findContours(markerMask, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

    if( contours.empty() )
    {
        cout << "Error: no seeds were placed. Aborting..." << endl;
        return -1;
    }

    Mat markers(markerMask.size(), CV_32S); // size of markers must be equal to original 3-channel image
    markers = Scalar::all(0); // original set to all zeros
    int idx = 0;
    for( ; idx >= 0; idx = hierarchy[idx][0], compCount++ ){
        drawContours(markers, contours, idx, Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX);

    }

    // here IDX takes as values (0, 1, 2...) as seeds placed in the image starting from 0
    // compCount takes as values (1, 2, 3, ...) as seeds placed starting from 1

    if( compCount == 0 )
    {
        cout << "Error: no components found. Aborting..." << endl;
        return -1;

    }

    // Add a segmented white background to the polygon and forbidden areas
    Mat add = imgOneChannel==255;
    add.convertTo(add,CV_32S);
    markers += add;

    // Create a color for each component
    vector<Vec3b> colorTab;
    for( i = 0; i < compCount; i++ )
    {
        int b = theRNG().uniform(0, 255);
        int g = theRNG().uniform(0, 255);
        int r = theRNG().uniform(0, 255);

        colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
    }

    double t = (double)getTickCount();

    // Count the number of conquered cells by each seed. Initially only one conquered cell (the proper seed)
    for( i = 1; i <= numberOfSeeds; i++){
        conqueredCells[i-1] = 1;
        // uncomment this if the seeds are placed in more than one pixel
        //int conqueredPixels = countNonZero(markers==i);
        //conqueredCells[i-1] = conqueredPixels;

    }

    // Count the number of cells that must be painted
    int numberOfCells = countNonZero(markers==0);

    // The algorithm is applied to the bigger image. The results are stored in the markers Mat
    watershed2( expandedPolygonImage, markers, percentages, conqueredCells, numberOfCells );
    t = (double)getTickCount() - t;
    int remainingCells = countNonZero(markers==0);
    printf( "Execution time = %gms\n", t*1000./getTickFrequency() );

    // Create a Matrix to paint the results with one color per segmented area.
    wshed = Mat(markers.size(), CV_8UC3);

    for( i = 0; i < markers.rows; i++ )
    {
        for( j = 0; j < markers.cols; j++ )
        {
            int index = markers.at<int>(i,j);
            if( index == -1 )
            {
                wshed.at<Vec3b>(i,j) = Vec3b(255,255,255);

            }
            else if( index <= 0 || index > compCount )
            {
                    wshed.at<Vec3b>(i,j) = Vec3b(0,0,0);

            }
            else
            {
                wshed.at<Vec3b>(i,j) = colorTab[index - 1];

            }

        }

    }

    // Vectorize the results. The idea is to create a Matrix for each of the subareas of the final segmentation
    // and calculate the contours of that subarea for each Matrix. Then, approx each with a polygon.
    // We will do all this only if we have more than one seed. If we have only one seed with 100% perctg,
    // we create the images but left intact the initial polygon because it doesn't needed any aproximation.

    if(percentages[0] != 100)
    {

        // For each segmentation area (color), will create a gray Mat wich will contains 255 in the positions of the subarea
        // and 0 in the rest. The final output image of the watershed will be traversed only one time to create each of
        // the gray Mats for performance purposes, so a map of Mats will be created.
        // When using a c++ map with class objects, those classes need to define operator < if used as keys,
        // so for avoiding this using the Vec3b colors as the keys, will use string representations of them.
        std::map<string,Mat> subareasMap;
        string colors[colorTab.size()];
        for(unsigned int i=0; i<colorTab.size(); i++)
        {
            // Convert the Vec3b to a string that serves as key to the map
            ostringstream color;
            color << colorTab[i];
            string color_string = color.str();
            colors[i] = color_string;

            // Create the gray Mat and put it to the map
            Mat subarea(wshed.size(), CV_8UC1);
            subarea = Scalar::all(0);
            subareasMap[color_string] = subarea;

        }

        // Traverse the output matrix and create the subareas matrix
        for(int i=0; i<wshed.rows; i++)
        {
            for(int j=0; j<wshed.cols; j++)
            {
                ostringstream color;
                color << wshed.at<Vec3b>(i, j);
                string color_string = color.str();

                // Only colors assigned to subareas must be taken into account
                int appereances = subareasMap.count(color_string);
                if(appereances == 1) // only one Mat per segmentation color
                {
                    Mat certain_subarea = subareasMap[color_string];
                    certain_subarea.at<unsigned char>(i, j) = 255;

                }

            }
        }

        // For each color, find the contours of the subarea and aprox a polygon
        cout << "\nInfo before applying polygon approximation: " << endl;
        vector<vector<Point> > color_contours[colorTab.size()];
        for(unsigned int i=0; i<colorTab.size(); i++)
        {
            Mat subarea = subareasMap[colors[i]];
            Mat subarea_copy;
            subarea.copyTo(subarea_copy);
            vector<Vec4i> hierarchy;
            vector<vector<Point> > contours;
            findContours(subarea_copy, contours, hierarchy, CV_RETR_CCOMP, CHAIN_APPROX_SIMPLE);
            cout << "- Number of contours for color " << colorTab[i] << ": " << contours.size() << endl;
            for(unsigned int k=0; k<contours.size(); k++)
            {
                cout << "---- Number of points for contour " << k << ": " << contours[k].size() << endl;

            }
            color_contours[i].resize(contours.size());
            for(unsigned int j = 0; j < contours.size(); j++ )
            {
                approxPolyDP(contours[j], color_contours[i][j], 3, true);

            }

        }

        cout << "\nInfo after applying polygon approximation: " << endl;
        for(unsigned int i=0; i<colorTab.size(); i++)
        {
            cout << "- Number of contours for color " << colorTab[i] << ": " << color_contours[i].size() << endl;
            for(unsigned int j=0; j<color_contours[i].size(); j++)
            {
                cout << "---- Number of points for contour " << j << ": " << color_contours[i][j].size() << endl;

            }

        }

        // generate utm/gps subareas
        save_contours_to_disk(color_contours, colorTab.size(), percentages);

    }

    // save the images in disk, will flip them so the output Mats are modified. Any
    save_images_to_disk();

    cout << "\nNumber of remaining pixels without segmentation: " << remainingCells << endl;
    cout << "\nProgram finished. Press any key to continue." << endl;

    // uncomment to show windows with the results //
    /*
    namedWindow( "image", 1 );
    namedWindow( "watershed transform", 1 );
    imshow( "image", viewportImg );
    imshow( "watershed transform", wshed );
    waitKey(0); //waits until a key is pressed;
    */

    return remainingCells;
}

/// TODO: permitir que el algoritmo tome un polígono con degradado y realice el flooding dando prioridad a los pixeles que estén más cerca de los bordes

void watershed2( InputArray _src, InputOutputArray markers, int* percentages, int* conqueredCells, int numberOfCells )
{
    Mat src = _src.getMat();
    CvMat c_src = _src.getMat(), c_markers = markers.getMat();
    cvWatershed2( &c_src, &c_markers, percentages, conqueredCells, numberOfCells );
}

void cvWatershed2( const CvArr* srcarr, CvArr* dstarr, int* percentages, int* conqueredCells, int numberOfCells )
{
    const int IN_QUEUE = -2;
    const int WSHED = -1;
    const int NQ = 256;
    cv::Ptr<CvMemStorage> storage;

    CvMat sstub, *src;
    CvMat dstub, *dst;
    CvSize size;
    CvWSNode* free_node = 0, *node;
    CvWSQueue q[NQ];
    int active_queue;
    int i, j;
    int db, dg, dr;
    int* mask;
    uchar* img;
    int mstep, istep;
    int subs_tab[513];

    // MAX(a,b) = b + MAX(a-b,0)
    #define ws_max(a,b) ((b) + subs_tab[(a)-(b)+NQ])
    // MIN(a,b) = a - MAX(a-b,0)
    #define ws_min(a,b) ((a) - subs_tab[(a)-(b)+NQ])

    #define ws_push(idx,mofs,iofs)  \
    {                               \
        if( !free_node )            \
            free_node = icvAllocWSNodes( storage );\
        node = free_node;           \
        free_node = free_node->next;\
        node->next = 0;             \
        node->mask_ofs = mofs;      \
        node->img_ofs = iofs;       \
        if( q[idx].last )           \
            q[idx].last->next=node; \
        else                        \
            q[idx].first = node;    \
        q[idx].last = node;         \
    }

    #define ws_pop(idx,mofs,iofs)   \
    {                               \
        node = q[idx].first;        \
        q[idx].first = node->next;  \
        if( !node->next )           \
            q[idx].last = 0;        \
        node->next = free_node;     \
        free_node = node;           \
        mofs = node->mask_ofs;      \
        iofs = node->img_ofs;       \
    }

    #define c_diff(ptr1,ptr2,diff)      \
    {                                   \
        db = abs((ptr1)[0] - (ptr2)[0]);\
        dg = abs((ptr1)[1] - (ptr2)[1]);\
        dr = abs((ptr1)[2] - (ptr2)[2]);\
        diff = ws_max(db,dg);           \
        diff = ws_max(diff,dr);         \
        assert( 0 <= diff && diff <= 255 ); \
    }

    src = cvGetMat( srcarr, &sstub );
    dst = cvGetMat( dstarr, &dstub );

    if( CV_MAT_TYPE(src->type) != CV_8UC3 )
        CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 3-channel input images are supported" );

    if( CV_MAT_TYPE(dst->type) != CV_32SC1 )
        CV_Error( CV_StsUnsupportedFormat,
            "Only 32-bit, 1-channel output images are supported" );

    if( !CV_ARE_SIZES_EQ( src, dst ))
        CV_Error( CV_StsUnmatchedSizes, "The input and output images must have the same size" );

    //size = cvGetMatSize(src);
    size.width = src->width;
    size.height = src->height;
    storage = cvCreateMemStorage();

    istep = src->step;
    img = src->data.ptr;
    mstep = dst->step / sizeof(mask[0]);
    mask = dst->data.i;

    memset( q, 0, NQ*sizeof(q[0]) );

    for( i = 0; i < 256; i++ )
        subs_tab[i] = 0;
    for( i = 256; i <= 512; i++ )
        subs_tab[i] = i - 256;

    // draw a pixel-wide border of dummy "watershed" (i.e. boundary) pixels
    for( j = 0; j < size.width; j++ )
        mask[j] = mask[j + mstep*(size.height-1)] = WSHED;

    // initial phase: put all the neighbor pixels of each marker to the ordered queue -
    // determine the initial boundaries of the basins
    for( i = 1; i < size.height-1; i++ )
    {
        img += istep; mask += mstep;
        mask[0] = mask[size.width-1] = WSHED;

        for( j = 1; j < size.width-1; j++ )
        {
            int* m = mask + j;
            if( m[0] < 0 ) m[0] = 0;
            if( m[0] == 0 && (m[-1] > 0 || m[1] > 0 || m[-mstep] > 0 || m[mstep] > 0) )
            {
                uchar* ptr = img + j*3;
                int idx = 256, t;
                if( m[-1] > 0 )
                    c_diff( ptr, ptr - 3, idx );
                if( m[1] > 0 )
                {
                    c_diff( ptr, ptr + 3, t );
                    idx = ws_min( idx, t );
                }
                if( m[-mstep] > 0 )
                {
                    c_diff( ptr, ptr - istep, t );
                    idx = ws_min( idx, t );
                }
                if( m[mstep] > 0 )
                {
                    c_diff( ptr, ptr + istep, t );
                    idx = ws_min( idx, t );
                }
                assert( 0 <= idx && idx <= 255 );
                ws_push( idx, i*mstep + j, i*istep + j*3 );
                // the number of queues tou put
                //cout << "IDX: " << idx << endl;
                m[0] = IN_QUEUE;
            }
        }
    }

    // find the first non-empty queue
    for( i = 0; i < NQ; i++ )
        if( q[i].first )
            break;

    // if there is no markers, exit immediately
    if( i == NQ )
        return;

    active_queue = i;
    img = src->data.ptr;
    mask = dst->data.i;

    // recursively fill the basins
    for(;;)
    {
        int mofs, iofs;
        int lab = 0, t;
        int* m;
        uchar* ptr;

        if( q[active_queue].first == 0 )
        {
            for( i = active_queue+1; i < NQ; i++ )
                if( q[i].first )
                    break;
            if( i == NQ )
                break;
            active_queue = i;
        }

        ws_pop( active_queue, mofs, iofs );

        m = mask + mofs;
        ptr = img + iofs;
        t = m[-1];
        if( t > 0 ) lab = t;
        t = m[1];
        if( t > 0 )
        {
            if( lab == 0 ) lab = t;
            else if( t != lab ) lab = WSHED;
        }
        t = m[-mstep];
        if( t > 0 )
        {
            if( lab == 0 ) lab = t;
            else if( t != lab ) lab = WSHED;
        }
        t = m[mstep];
        if( t > 0 )
        {
            if( lab == 0 ) lab = t;
            else if( t != lab ) lab = WSHED;
        }
        assert( lab != 0 );

        // check if the assigned marker (lab) has conquered the percentage of cells
        if(lab != WSHED){
            int actualPercentage = (conqueredCells[lab-1]/((double) numberOfCells))*100;
            if(actualPercentage >= percentages[lab-1]){
                if(active_queue == 0 || active_queue == 255){
                    m[0] = WSHED;

                }
                continue;

            } else{
                conqueredCells[lab-1]++;

            }
        }

        m[0] = lab;
        //cout << "Active Queue: " << active_queue << endl;

        if( lab == WSHED )
            continue;

        if( m[-1] == 0 )
        {
            c_diff( ptr, ptr - 3, t );
            ws_push( t, mofs - 1, iofs - 3 );
            active_queue = ws_min( active_queue, t );
            m[-1] = IN_QUEUE;
        }
        if( m[1] == 0 )
        {
            c_diff( ptr, ptr + 3, t );
            ws_push( t, mofs + 1, iofs + 3 );
            active_queue = ws_min( active_queue, t );
            m[1] = IN_QUEUE;
        }
        if( m[-mstep] == 0 )
        {
            c_diff( ptr, ptr - istep, t );
            ws_push( t, mofs - mstep, iofs - istep );
            active_queue = ws_min( active_queue, t );
            m[-mstep] = IN_QUEUE;
        }
        if( m[mstep] == 0 )
        {
            c_diff( ptr, ptr + istep, t );
            ws_push( t, mofs + mstep, iofs + istep );
            active_queue = ws_min( active_queue, t );
            m[mstep] = IN_QUEUE;
        }
    }
}

static CvWSNode* icvAllocWSNodes( CvMemStorage* storage )
{
    CvWSNode* n = 0;

    int i, count = (storage->block_size - sizeof(CvMemBlock))/sizeof(*n) - 1;

    n = (CvWSNode*)cvMemStorageAlloc( storage, count*sizeof(*n) );
    for( i = 0; i < count-1; i++ )
        n[i].next = n + i + 1;
    n[count-1].next = 0;

    return n;
}

Mat createMatImg(int numberOfSeeds)
{
    Mat outputMat(0, 0, CV_8UC3);
    string line;
    ifstream polygon_file(polygonFilePath.c_str());
    double latitude, longitude;

    if (polygon_file.is_open())
    {
        // read the outter polygon
        utm_polygon.push_back(vector<cv::Point2d>());
        int index = 0;
        while ( getline(polygon_file,line) )
        {
            // avoid empty lines
            if(line.compare(string("")) == 0)
            {
                continue;
            }
            string number; // Have a buffer string
            stringstream ss(line); // Insert the string into a stream
            vector<string> tokens; // Create vector to hold our words
            ss >> number;
            latitude = atof(number.c_str());
            ss >> number;
            longitude = atof(number.c_str());

            if(latitude == -1 || longitude == -1 ){
                // check if there are more points->forbidden areas
                index++;
                utm_polygon.push_back(vector<cv::Point2d>());

            }
            else{
                // insert the point and calculate min/max values
                cv::Point2d vertex(latitude, longitude);
                utm_polygon[index].push_back(vertex);

                if(latitude < min_x){
                    min_x = latitude;

                }

                if(longitude < min_y){
                    min_y = longitude;

                }

                if(latitude > max_x){
                    max_x = latitude;

                }

                if(longitude > max_y){
                    max_y = longitude;

                }

            }

        }

    }
    else
    {
        cout << "Unable to open file" << endl;
        return outputMat;

    }

    polygon_file.close();
    utm_polygon.pop_back();

    // check if more seeds than vertex. If that's the case, return a size 0 matrix
    if(utm_polygon[0].size() < numberOfSeeds)
    {
        return outputMat;
    }

    width = max_x - min_x;
    height = max_y - min_y;

    printf("max_x: %lf\n", max_x);
    printf("max_y: %lf\n", max_y);
    printf("min_x: %lf\n", min_x);
    printf("min_y: %lf\n", min_y);

    scale_ratio = ((double) desired_width)/width;
    final_w = width*scale_ratio; // set 5 additional pixels per side
    final_h = height*scale_ratio; // set 5 additional pixels per side
    /*
    printf("Image width: %d\n", width);
    printf("Image height: %d\n", height);
    printf("Final image width: %d\n", final_w);
    printf("Final image height: %d\n", final_h);
    printf("Scale ratio: %lf\n", scale_ratio);
    */
    // save to disk config parameters such as min_x, min_y, etc, to let other apps work with utm points over output image
    save_config_to_disk();

    for(unsigned int i=0;i<utm_polygon.size(); i++){
        cpp_polygon.push_back(vector<cv::Point>());
        scaled_polygon.push_back(vector<cv::Point>());
        viewport_polygon.push_back(vector<cv::Point>());
        for(unsigned int j=0; j<utm_polygon[i].size(); j++){
            // translate the floating points to integer points near (0,0) origin by substracting minimal values
            int x_point = (int) (utm_polygon[i][j].x - min_x);
            int y_point = (int) (utm_polygon[i][j].y - min_y);
            int x_scaled = x_point*scale_ratio;
            int y_scaled = y_point*scale_ratio;

            if(x_scaled >= final_w)
            {
                x_scaled = final_w-1;

            }

            if(y_scaled >= final_h)
            {
                y_scaled = final_h-1;

            }

            Point point(x_point, y_point); // the point resultant of translating from utm
            Point scaledPoint(x_scaled, y_scaled); // the point resultant of translating to a fixed image width
            Point viewportPoint(x_scaled + added_lines/2, y_scaled + added_lines/2); // apply a offset to each point to center the polygon
            cpp_polygon[i].push_back(point);
            scaled_polygon[i].push_back(scaledPoint);
            viewport_polygon[i].push_back(viewportPoint);

        }

    }

    outputMat = Mat(final_h, final_w, CV_8UC3);
    outputMat = Scalar::all(255);

    // paint the outer scaled polygon
    cv::Point poly[1][scaled_polygon[0].size()];
    for(unsigned int i=0; i<scaled_polygon[0].size();i++)
    {
        poly[0][i] = scaled_polygon[0][i];

    }
    const cv::Point* ppt[1] = {poly[0]};
    int npt[] = {scaled_polygon[0].size()};
    fillPoly(outputMat, ppt, npt, 1, Scalar( 0, 0, 0 ), 0 );

    // paint the forbidden areas
    for(unsigned int k=1; k<scaled_polygon.size(); k++)
    {
        // paint the outer polygon
        cv::Point poly[1][scaled_polygon[k].size()];
        for(unsigned int i=0; i<scaled_polygon[k].size();i++)
        {
            poly[0][i] = scaled_polygon[k][i];

        }
        const cv::Point* ppt2[1] = {poly[0]};
        int npt2[] = {scaled_polygon[k].size()};
        fillPoly(outputMat, ppt2, npt2, 1, Scalar( 255, 255, 255 ), 0 );

    }

    return outputMat;

}

std::list<cv::Point> generate_seed_points(int numberOfSeeds)
{
    std::list<cv::Point> seedPointsList; // initially empty
    std::list<cv::Point> polygonPointsList(viewport_polygon[0].begin(), viewport_polygon[0].end());
    std::list<cv::Point>::iterator polyIterator = polygonPointsList.begin();
    cv::Point firstPoint(*polyIterator); // pick the first element as the first seed
    cv::Point centroid(firstPoint); // the sum of the assigned points
    seedPointsList.push_back(firstPoint);
    polygonPointsList.erase(polygonPointsList.begin()); // delete the first element
    numberOfSeeds--;
    double x_difference, y_difference, biggestDistanceToCentroid, distanceToCentroid;
    //cout << "Remaining seeds: " << numberOfSeeds << endl;
    while(numberOfSeeds > 0)
    {
        // take the first initially as the most far
        std::list<cv::Point>::iterator it = polygonPointsList.begin();
        std::list<cv::Point>::iterator mostFar = it;
        x_difference = ((double)centroid.x)/seedPointsList.size() - (*it).x;
        y_difference = ((double)centroid.y)/seedPointsList.size() - (*it).y;
        biggestDistanceToCentroid = sqrt( pow(x_difference, 2) + pow(y_difference, 2) );
        it++;

        while(it != polygonPointsList.end())
        {
            x_difference = ((double)centroid.x)/seedPointsList.size() - (*it).x;
            y_difference = ((double)centroid.y)/seedPointsList.size() - (*it).y;
            distanceToCentroid = sqrt( pow(x_difference, 2) + pow(y_difference, 2) );
            if(distanceToCentroid > biggestDistanceToCentroid)
            {
                biggestDistanceToCentroid = distanceToCentroid;
                mostFar = it;

            }

            it++;

        }

        seedPointsList.push_back(*mostFar);
        centroid += *mostFar;
        polygonPointsList.erase(mostFar);
        numberOfSeeds--;

    }

    return seedPointsList;

}

void save_contours_to_disk(vector<vector<Point> > *color_contours, int size, int* percentages)
{
    for(int i=0; i<size; i++)
    {
        string filename = polygonFilePath.substr(0, polygonFilePath.size()-4); // avoid the .txt chars
        ostringstream convert;   // stream used for the conversion
        convert << i;      // insert the index of the subarea
        convert << "_" << percentages[i];
        filename += string("_subarea") + convert.str() + string(".txt");
        ofstream text_file;
        text_file.open (filename.c_str());
        for(unsigned int j=0; j<color_contours[i].size(); j++)
        {
            for(unsigned int k=0; k<color_contours[i][j].size(); k++)
            {
                Point point = color_contours[i][j][k];
                point.x -= added_lines/2;
                point.y -= added_lines/2;
                point *= 1/scale_ratio;
                point.x += min_x;
                point.y += min_y;
                text_file << point.x << " " << point.y << endl;
            }

            text_file << "-1.0 -1.0" << endl;

        }
        text_file.close();

    }

}

void save_images_to_disk()
{
    // flip the images
    //flip(viewportImg, viewportImg, 0);
    //flip(wshed, wshed, 0);

    // write to disk
    imwrite(input_img_filename, expandedPolygonImage);
    imwrite(output_img_filename, wshed);

}

void save_config_to_disk()
{

    string filename = polygonFilePath.substr(0, polygonFilePath.find_last_of("p")); // get the dir of the poly file

    filename += string("config.txt");
    /*
    ofstream text_file;
    text_file.open (filename.c_str());
    text_file << min_x << endl;
    text_file << min_y << endl;
    text_file << scale_ratio << endl;
    text_file << output_img_filename << endl;
    text_file.close();
    */

    FILE * pFile;
    pFile = fopen (filename.c_str(), "w");
    fprintf(pFile, "%lf\n", min_x);
    fprintf(pFile, "%lf\n", min_y);
    fprintf(pFile, "%lf\n", scale_ratio);
    fprintf(pFile, "%d\n", added_lines);
    fprintf(pFile, "%s\n", output_img_filename.c_str());
    fprintf(pFile, "%s\n", "");
    fclose(pFile);

}


text:
<?php

namespace Rithis\ImagePlaceholderBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class RithisImagePlaceholderBundle extends Bundle
{
}


text:
#include <aws/ds/model/DeleteConditionalForwarderRequest.h>
#include <aws/core/utils/json/JsonSerializer.h>

#include <utility>

using namespace Aws::DirectoryService::Model;
using namespace Aws::Utils::Json;
using namespace Aws::Utils;

DeleteConditionalForwarderRequest::DeleteConditionalForwarderRequest() :
    m_directoryIdHasBeenSet(false),
    m_remoteDomainNameHasBeenSet(false)
{
}

Aws::String DeleteConditionalForwarderRequest::SerializePayload() const
{
  JsonValue payload;

  if(m_directoryIdHasBeenSet)
  {
   payload.WithString("DirectoryId", m_directoryId);

  }

  if(m_remoteDomainNameHasBeenSet)
  {
   payload.WithString("RemoteDomainName", m_remoteDomainName);

  }

  return payload.WriteReadable();
}

Aws::Http::HeaderValueCollection DeleteConditionalForwarderRequest::GetRequestSpecificHeaders() const
{
  Aws::Http::HeaderValueCollection headers;
  headers.insert(Aws::Http::HeaderValuePair("X-Amz-Target", "DirectoryService_20150416.DeleteConditionalForwarder"));
  return headers;

}


text:
<?php
namespace WScore\Form\Format;

use WScore\Form\Form;

class FormForm
{
    /**
     * @param Form $element
     * @return string
     */
    public static function toString( $element )
    {
        if( $element->isClosed() ) {
            return self::close( $element );
        }
        $html = ToString::htmlProperty( $element, 'id', 'class', 'style' );
        $html = '<' . $element->getTagName() . ' ' . $html . ' >' . "\n";
        $html = ToString::addLabel( $html, $element );
        return $html;
    }

    /**
     * @param Form $element
     * @return string
     */
    public static function close( $element )
    {
        return "</{$element->getTagName()}>";
    }
}