text:
var Zaggoware;
(function (Zaggoware) {
    var Tagging;
    (function (Tagging) {
        var Tagger = (function () {
            function Tagger($container) {
                this.$container = $container;
                this.tagList = new TagList(this);
                if ($container != null) {
                    this.$textBox = $container.find("input[type=text]");
                    this.$tagList = $container.find("ul.tag-list");
                }
            }
            Tagger.initialize = function () {
                Tagger.taggers = new Array();
                $(".tag-list-container").each(function () {
                    Tagger.taggers.push(new Tagger($(this)));
                });
            };
            Tagger.prototype.getTagList = function () {
                return this.tagList;
            };
            Tagger.prototype.getContainer = function () {
                return this.$container;
            };
            Tagger.prototype.getFieldName = function () {
                return this.$textBox.data("name");
            };
            Tagger.prototype.render = function () {
                this.$container = $("<div/>").addClass("tag-list-container");
                this.tagList.render();
                this.addEventHandlers();
            };
            Tagger.prototype.addEventHandlers = function () {
            };
            return Tagger;
        })();
        Tagging.Tagger = Tagger;
        var TagList = (function () {
            function TagList(tagger) {
                this.tagger = tagger;
                this.items = new Array();
            }
            TagList.prototype.getTagger = function () {
                return this.tagger;
            };
            TagList.prototype.addNewItem = function (label, hiddenValue) {
                var item = new TagListItem(this, label, hiddenValue);
                return this.addItem(item);
            };
            TagList.prototype.addItem = function (item) {
                this.items.push(item);
                return item;
            };
            TagList.prototype.removeItem = function (item) {
                var index = this.indexOf(item);
                if (index !== -1) {
                    this.items.splice(index, 1);
                }
                item.remove(false);
            };
            TagList.prototype.indexOf = function (item) {
                return $.inArray(item, this.items);
            };
            TagList.prototype.render = function () {
                if (this.$container != null) {
                    this.$container.remove();
                }
                this.$container = $("<ul/>").addClass("tag-list").appendTo(this.tagger.getContainer());
                for (var i = 0; i < this.items.length; i++) {
                    this.items[i].render();
                }
            };
            TagList.prototype.getContainer = function () {
                if (this.$container == null) {
                    this.render();
                }
                return this.$container;
            };
            return TagList;
        })();
        var TagListItem = (function () {
            function TagListItem(tagList, label, hiddenValue) {
                this.tagList = tagList;
                this.label = label;
                this.hiddenValue = hiddenValue;
            }
            TagListItem.prototype.getLabel = function () {
                return this.label != null ? this.label : (this.hiddenValue != null ? this.hiddenValue.toString() : '');
            };
            TagListItem.prototype.getHiddenValue = function () {
                return this.hiddenValue;
            };
            TagListItem.prototype.render = function () {
                if (this.$container != null) {
                    this.$container.remove();
                }
                this.$container = $("<li/>").addClass("tag-list-item");
                this.$label = $("<span/>").addClass("tag-list-item-label").text(this.getLabel()).appendTo(this.$container);
                this.$removeButton = $("<span/>").addClass("tag-list-item-remove").text("X").appendTo(this.$label);
                var fieldName = this.tagList.getTagger().getFieldName();
                var index = this.tagList.indexOf(this);
                if (index < 0) {
                    index = 0;
                }
                $("<input/>").attr("type", "hidden").attr("name", fieldName + "[" + index + "].Label").val(this.getLabel()).appendTo(this.$container);
                $("<input/>").attr("type", "hidden").attr("name", fieldName + "[" + index + "].HiddenValue").attr("value", this.getHiddenValue()).appendTo(this.$container);
                this.tagList.getContainer().append(this.$container);
                this.addEventHandlers();
            };
            TagListItem.prototype.remove = function (removeFromTagList) {
                if (removeFromTagList === void 0) { removeFromTagList = true; }
                if (removeFromTagList) {
                    this.tagList.removeItem(this);
                }
                if (this.$container != null) {
                    this.$container.remove();
                    this.$container = null;
                }
            };
            TagListItem.prototype.addEventHandlers = function () {
                var _this = this;
                this.$container.find(".tag-list-item-remove").click(function () {
                    _this.remove();
                });
            };
            return TagListItem;
        })();
    })(Tagging = Zaggoware.Tagging || (Zaggoware.Tagging = {}));
})(Zaggoware || (Zaggoware = {}));
//# sourceMappingURL=Tagger.js.map


text:
package me

import (
	usermodel "github.com/gotokatsuya/lboard/model/user"
)

// GetResponse ...
type GetResponse struct {
	Instance instance
}

// NewGetResponse ...
func NewGetResponse() *GetResponse {
	return &GetResponse{}
}

// Convert ...
func (r *GetResponse) Convert(user *usermodel.Entity) error {
	ins := instance{}
	if err := ins.Convert(user); err != nil {
		return err
	}
	r.Instance = ins
	return nil
}

redpajama_set_name: RedPajamaGithub


text:
/*
Error: Undefined variable: "$white".
        on line 14 of /Users/lgwin/Documents/Projects/Activate/site/css/_typography.scss

9:
10: body {
11: 	font-family: 'Panton W01 Regular', 'Roboto', 'Helvetica', 'Arial', sans-serif;
12: 	padding: 0; margin: 0;
13: 	font-size: $rem;
14: 	color: $white;
15: }
16:
17: h1, h2, h3, h4, h5, h6, p {
18: 	padding: 0; margin: 0;
19: }

Backtrace:
/Users/lgwin/Documents/Projects/Activate/site/css/_typography.scss:14
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/script/tree/variable.rb:49:in `_perform'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/script/tree/node.rb:50:in `perform'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:395:in `visit_prop'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:36:in `visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:79:in `block in with_base'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:115:in `with_frame'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:79:in `with_base'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:158:in `visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:431:in `block (2 levels) in visit_rule'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:431:in `map'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:431:in `block in visit_rule'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:429:in `visit_rule'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:36:in `visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:79:in `block in with_base'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:115:in `with_frame'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:79:in `with_base'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:158:in `visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:52:in `block in visit_children'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:52:in `map'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:52:in `visit_children'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:167:in `block in visit_children'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:166:in `visit_children'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:36:in `block in visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:186:in `visit_root'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:36:in `visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:157:in `visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:8:in `visit'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/root_node.rb:36:in `css_tree'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/root_node.rb:20:in `render'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/engine.rb:278:in `render'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/exec/sass_scss.rb:423:in `run'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/exec/sass_scss.rb:63:in `process_result'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/exec/base.rb:52:in `parse'
/Applications/CodeKit.app/Contents/Resources/engines/scss/lib/sass/exec/base.rb:19:in `parse!'
/Applications/CodeKit.app/Contents/Resources/engines/scss/bin/scss:13:in `<main>'
*/
body:before {
  white-space: pre;
  font-family: monospace;
  content: "Error: Undefined variable: \"$white\".\A         on line 14 of /Users/lgwin/Documents/Projects/Activate/site/css/_typography.scss\A \A 9: \A 10: body {\A 11: 	font-family: 'Panton W01 Regular', 'Roboto', 'Helvetica', 'Arial', sans-serif;\A 12: 	padding: 0; margin: 0;\A 13: 	font-size: $rem;\A 14: 	color: $white;\A 15: }\A 16: \A 17: h1, h2, h3, h4, h5, h6, p {\A 18: 	padding: 0; margin: 0;\A 19: }"; }


text:
package org.jkiss.dbeaver.model.struct.cache;

import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObject;

import java.util.Collection;
import java.util.List;

/**
 * Objects cache
 */
public interface DBSObjectCache<OWNER extends DBSObject, OBJECT extends DBSObject> {

    @NotNull
    Collection<OBJECT> getAllObjects(@NotNull DBRProgressMonitor monitor, @Nullable OWNER owner)
        throws DBException;

    @NotNull
    List<OBJECT> getCachedObjects();

    @Nullable
    OBJECT getObject(@NotNull DBRProgressMonitor monitor, @NotNull OWNER owner, @NotNull String name)
        throws DBException;

    @Nullable
    OBJECT getCachedObject(@NotNull String name);

    /**
     * True if all available objects were cached
     */
    boolean isFullyCached();

    /**
     * Adds specified object to cache
     * @param object object to cache
     */
    void cacheObject(@NotNull OBJECT object);

    /**
     * Sets new cache contents. setCache(getCachedObjects()) will reset named cache.
     * Set fullyCache flag to true.
     * @param objects new cache contents
     */
    void setCache(List<OBJECT> objects);

    /**
     * Removes specified object from cache
     * @param object object to remove
     * @param resetFullCache if true resets fullyCached flag. May be used to refresh linked objects.
     */
    void removeObject(@NotNull OBJECT object, boolean resetFullCache);

    void renameObject(@NotNull OBJECT object, @NotNull String oldName, @NotNull String newName);

    /**
     * Clears all cache
     */
    void clearCache();

}


text:
A flappy bird clone made in go.

![Flappy Gopher](flappy_gopher.png)

Based on [this video](https://www.youtube.com/watch?v=aYkxFbd6luY) and [this project](https://github.com/campoy/flappy) by [Francesc Campoy](https://github.com/campoy), also [this project](https://github.com/shabinesh/flappy) by [Sab](https://github.com/shabinesh)

# Play

Just run "make run" and use any button to jump


text:
<?php
if (!defined('ABSPATH'))
    exit;
?>

    This theme requires posts with at least one image and a number of posts like
    3, 6, 9, ...

        Max posts
        <?php $controls->text('theme_max_posts', 5); ?>

        Categories
        <?php $controls->categories_group('theme_categories'); ?>

<?php include WP_PLUGIN_DIR . '/newsletter/emails/themes/default/social-options.php'; ?>


text:
package com.colorcorrection.eecs582.colorcorrection;

import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.hardware.Camera ;
import android.content.Context ;
import java.io.IOException;

/**
 * Created by joshalbrecht on 2/2/16.
 */
public class cameraView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder mHolder ;
    private Camera mCamera ;

    public cameraView ( Context context, Camera camera){

        super ( context ) ;

        mHolder = getHolder() ;
        mHolder.addCallback(this);

        mHolder.setType( SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) ;
    }

    public void surfaceCreated( SurfaceHolder holder ){

        try{

            mCamera.setPreviewDisplay( holder );
            mCamera.startPreview() ;

        } catch ( IOException e ){

        }
    }

    public void surfaceChanged( SurfaceHolder holder, int format, int w, int h ){

    }

    public void surfaceDestroyed( SurfaceHolder holder ){

    }

}


text:
cask 'racket' do
  version '6.12'
  sha256 '54fbee6a967209c62c814f60ba00ca105f01c69a8f1a9f4bfa21525698398a31'

  url "https://mirror.racket-lang.org/installers/#{version}/racket-#{version}-x86_64-macosx.dmg"
  appcast 'https://download.racket-lang.org/all-versions.html'
  name 'Racket'
  homepage 'https://racket-lang.org/'

  suite "Racket v#{version}"
  binary "#{appdir}/Racket v#{version}/bin/drracket"
  binary "#{appdir}/Racket v#{version}/bin/gracket"
  binary "#{appdir}/Racket v#{version}/bin/gracket-text"
  binary "#{appdir}/Racket v#{version}/bin/mred"
  binary "#{appdir}/Racket v#{version}/bin/mred-text"
  binary "#{appdir}/Racket v#{version}/bin/mzc"
  binary "#{appdir}/Racket v#{version}/bin/mzpp"
  binary "#{appdir}/Racket v#{version}/bin/mzscheme"
  binary "#{appdir}/Racket v#{version}/bin/mztext"
  binary "#{appdir}/Racket v#{version}/bin/pdf-slatex"
  binary "#{appdir}/Racket v#{version}/bin/plt-games"
  binary "#{appdir}/Racket v#{version}/bin/plt-help"
  binary "#{appdir}/Racket v#{version}/bin/plt-r5rs"
  binary "#{appdir}/Racket v#{version}/bin/plt-r6rs"
  binary "#{appdir}/Racket v#{version}/bin/plt-web-server"
  binary "#{appdir}/Racket v#{version}/bin/racket"
  binary "#{appdir}/Racket v#{version}/bin/raco"
  binary "#{appdir}/Racket v#{version}/bin/scribble"
  binary "#{appdir}/Racket v#{version}/bin/setup-plt"
  binary "#{appdir}/Racket v#{version}/bin/slatex"
  binary "#{appdir}/Racket v#{version}/bin/slideshow"
  binary "#{appdir}/Racket v#{version}/bin/swindle"
end


text:
package org.springframework.boot.devtools.filewatch;

import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

import org.springframework.boot.devtools.filewatch.ChangedFile.Type;
import org.springframework.util.FileCopyUtils;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

/**
 * Tests for {@link FileSystemWatcher}.
 *
 * @author Phillip Webb
 */
public class FileSystemWatcherTests {

	@Rule
	public ExpectedException thrown = ExpectedException.none();

	private FileSystemWatcher watcher;

	private List<Set<ChangedFiles>> changes = Collections
			.synchronizedList(new ArrayList<Set<ChangedFiles>>());

	@Rule
	public TemporaryFolder temp = new TemporaryFolder();

	@Before
	public void setup() throws Exception {
		setupWatcher(20, 10);
	}

	@Test
	public void pollIntervalMustBePositive() throws Exception {
		this.thrown.expect(IllegalArgumentException.class);
		this.thrown.expectMessage("PollInterval must be positive");
		new FileSystemWatcher(true, 0, 1);
	}

	@Test
	public void quietPeriodMustBePositive() throws Exception {
		this.thrown.expect(IllegalArgumentException.class);
		this.thrown.expectMessage("QuietPeriod must be positive");
		new FileSystemWatcher(true, 1, 0);
	}

	@Test
	public void pollIntervalMustBeGreaterThanQuietPeriod() throws Exception {
		this.thrown.expect(IllegalArgumentException.class);
		this.thrown.expectMessage("PollInterval must be greater than QuietPeriod");
		new FileSystemWatcher(true, 1, 1);
	}

	@Test
	public void listenerMustNotBeNull() throws Exception {
		this.thrown.expect(IllegalArgumentException.class);
		this.thrown.expectMessage("FileChangeListener must not be null");
		this.watcher.addListener(null);
	}

	@Test
	public void cannotAddListenerToStartedListener() throws Exception {
		this.thrown.expect(IllegalStateException.class);
		this.thrown.expectMessage("FileSystemWatcher already started");
		this.watcher.start();
		this.watcher.addListener(mock(FileChangeListener.class));
	}

	@Test
	public void sourceFolderMustNotBeNull() throws Exception {
		this.thrown.expect(IllegalArgumentException.class);
		this.thrown.expectMessage("Folder must not be null");
		this.watcher.addSourceFolder(null);
	}

	@Test
	public void sourceFolderMustExist() throws Exception {
		File folder = new File("does/not/exist");
		assertThat(folder.exists()).isFalse();
		this.thrown.expect(IllegalArgumentException.class);
		this.thrown.expectMessage(
				"Folder '" + folder + "' must exist and must be a directory");
		this.watcher.addSourceFolder(folder);
	}

	@Test
	public void sourceFolderMustBeADirectory() throws Exception {
		File folder = new File("pom.xml");
		assertThat(folder.isFile()).isTrue();
		this.thrown.expect(IllegalArgumentException.class);
		this.thrown.expectMessage("Folder 'pom.xml' must exist and must be a directory");
		this.watcher.addSourceFolder(new File("pom.xml"));
	}

	@Test
	public void cannotAddSourceFolderToStartedListener() throws Exception {
		this.thrown.expect(IllegalStateException.class);
		this.thrown.expectMessage("FileSystemWatcher already started");
		this.watcher.start();
		this.watcher.addSourceFolder(this.temp.newFolder());
	}

	@Test
	public void addFile() throws Exception {
		File folder = startWithNewFolder();
		File file = touch(new File(folder, "test.txt"));
		this.watcher.stopAfter(1);
		ChangedFiles changedFiles = getSingleChangedFiles();
		ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
		assertThat(changedFiles.getFiles()).contains(expected);
	}

	@Test
	public void addNestedFile() throws Exception {
		File folder = startWithNewFolder();
		File file = touch(new File(new File(folder, "sub"), "text.txt"));
		this.watcher.stopAfter(1);
		ChangedFiles changedFiles = getSingleChangedFiles();
		ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
		assertThat(changedFiles.getFiles()).contains(expected);
	}

	@Test
	public void waitsForPollingInterval() throws Exception {
		setupWatcher(10, 1);
		File folder = startWithNewFolder();
		touch(new File(folder, "test1.txt"));
		while (this.changes.size() != 1) {
			Thread.sleep(10);
		}
		touch(new File(folder, "test2.txt"));
		this.watcher.stopAfter(1);
		assertThat(this.changes.size()).isEqualTo(2);
	}

	@Test
	public void waitsForQuietPeriod() throws Exception {
		setupWatcher(300, 200);
		File folder = startWithNewFolder();
		for (int i = 0; i < 10; i++) {
			touch(new File(folder, i + "test.txt"));
			Thread.sleep(100);
		}
		this.watcher.stopAfter(1);
		ChangedFiles changedFiles = getSingleChangedFiles();
		assertThat(changedFiles.getFiles().size()).isEqualTo(10);
	}

	@Test
	public void withExistingFiles() throws Exception {
		File folder = this.temp.newFolder();
		touch(new File(folder, "test.txt"));
		this.watcher.addSourceFolder(folder);
		this.watcher.start();
		File file = touch(new File(folder, "test2.txt"));
		this.watcher.stopAfter(1);
		ChangedFiles changedFiles = getSingleChangedFiles();
		ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
		assertThat(changedFiles.getFiles()).contains(expected);
	}

	@Test
	public void multipleSources() throws Exception {
		File folder1 = this.temp.newFolder();
		File folder2 = this.temp.newFolder();
		this.watcher.addSourceFolder(folder1);
		this.watcher.addSourceFolder(folder2);
		this.watcher.start();
		File file1 = touch(new File(folder1, "test.txt"));
		File file2 = touch(new File(folder2, "test.txt"));
		this.watcher.stopAfter(1);
		Set<ChangedFiles> change = getSingleOnChange();
		assertThat(change.size()).isEqualTo(2);
		for (ChangedFiles changedFiles : change) {
			if (changedFiles.getSourceFolder().equals(folder1)) {
				ChangedFile file = new ChangedFile(folder1, file1, Type.ADD);
				assertThat(changedFiles.getFiles()).containsOnly(file);
			}
			else {
				ChangedFile file = new ChangedFile(folder2, file2, Type.ADD);
				assertThat(changedFiles.getFiles()).containsOnly(file);
			}
		}
	}

	@Test
	public void multipleListeners() throws Exception {
		File folder = this.temp.newFolder();
		final Set<ChangedFiles> listener2Changes = new LinkedHashSet<>();
		this.watcher.addSourceFolder(folder);
		this.watcher.addListener(new FileChangeListener() {
			@Override
			public void onChange(Set<ChangedFiles> changeSet) {
				listener2Changes.addAll(changeSet);
			}
		});
		this.watcher.start();
		File file = touch(new File(folder, "test.txt"));
		this.watcher.stopAfter(1);
		ChangedFiles changedFiles = getSingleChangedFiles();
		ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
		assertThat(changedFiles.getFiles()).contains(expected);
		assertThat(listener2Changes).isEqualTo(this.changes.get(0));
	}

	@Test
	public void modifyDeleteAndAdd() throws Exception {
		File folder = this.temp.newFolder();
		File modify = touch(new File(folder, "modify.txt"));
		File delete = touch(new File(folder, "delete.txt"));
		this.watcher.addSourceFolder(folder);
		this.watcher.start();
		FileCopyUtils.copy("abc".getBytes(), modify);
		delete.delete();
		File add = touch(new File(folder, "add.txt"));
		this.watcher.stopAfter(1);
		ChangedFiles changedFiles = getSingleChangedFiles();
		Set<ChangedFile> actual = changedFiles.getFiles();
		Set<ChangedFile> expected = new HashSet<>();
		expected.add(new ChangedFile(folder, modify, Type.MODIFY));
		expected.add(new ChangedFile(folder, delete, Type.DELETE));
		expected.add(new ChangedFile(folder, add, Type.ADD));
		assertThat(actual).isEqualTo(expected);
	}

	@Test
	public void withTriggerFilter() throws Exception {
		File folder = this.temp.newFolder();
		File file = touch(new File(folder, "file.txt"));
		File trigger = touch(new File(folder, "trigger.txt"));
		this.watcher.addSourceFolder(folder);
		this.watcher.setTriggerFilter(new FileFilter() {

			@Override
			public boolean accept(File file) {
				return file.getName().equals("trigger.txt");
			}

		});
		this.watcher.start();
		FileCopyUtils.copy("abc".getBytes(), file);
		Thread.sleep(100);
		assertThat(this.changes.size()).isEqualTo(0);
		FileCopyUtils.copy("abc".getBytes(), trigger);
		this.watcher.stopAfter(1);
		ChangedFiles changedFiles = getSingleChangedFiles();
		Set<ChangedFile> actual = changedFiles.getFiles();
		Set<ChangedFile> expected = new HashSet<>();
		expected.add(new ChangedFile(folder, file, Type.MODIFY));
		assertThat(actual).isEqualTo(expected);
	}

	private void setupWatcher(long pollingInterval, long quietPeriod) {
		this.watcher = new FileSystemWatcher(false, pollingInterval, quietPeriod);
		this.watcher.addListener(new FileChangeListener() {
			@Override
			public void onChange(Set<ChangedFiles> changeSet) {
				FileSystemWatcherTests.this.changes.add(changeSet);
			}
		});
	}

	private File startWithNewFolder() throws IOException {
		File folder = this.temp.newFolder();
		this.watcher.addSourceFolder(folder);
		this.watcher.start();
		return folder;
	}

	private ChangedFiles getSingleChangedFiles() {
		Set<ChangedFiles> singleChange = getSingleOnChange();
		assertThat(singleChange.size()).isEqualTo(1);
		return singleChange.iterator().next();
	}

	private Set<ChangedFiles> getSingleOnChange() {
		assertThat(this.changes.size()).isEqualTo(1);
		return this.changes.get(0);
	}

	private File touch(File file) throws FileNotFoundException, IOException {
		file.getParentFile().mkdirs();
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		fileOutputStream.close();
		return file;
	}

}


text:
using System;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Threading.Tasks;

using Microsoft.VisualStudio.Services.Agent.Util;

using Newtonsoft.Json;

namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts
{
    [ServiceLocator(Default = typeof(GitHubHttpClient))]
    public interface IGitHubHttpClient : IAgentService
    {
        GitHubRepository GetUserRepo(string accessToken, string repository);
    }

    public class GitHubHttpClient : AgentService, IGitHubHttpClient
    {
        private const string GithubRepoUrlFormat = "https://api.github.com/repos/{0}";

        public GitHubRepository GetUserRepo(string accessToken, string repositoryName)
        {
            string errorMessage;
            string url = StringUtil.Format(GithubRepoUrlFormat, repositoryName);
            GitHubRepository repository = QueryItem<GitHubRepository>(accessToken, url, out errorMessage);

            if (!string.IsNullOrEmpty(errorMessage))
            {
                throw new InvalidOperationException(errorMessage);
            }

            return repository;
        }

        private T QueryItem<T>(string accessToken, string url, out string errorMessage)
        {
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);

            request.Headers.Add("Accept", "application/vnd.GitHubData.V3+json");
            request.Headers.Add("Authorization", "Token " + accessToken);
            request.Headers.Add("User-Agent", "VSTS-Agent/" + Constants.Agent.Version);

            int httpRequestTimeoutSeconds;
            if (!int.TryParse(Environment.GetEnvironmentVariable("VSTS_HTTP_TIMEOUT") ?? string.Empty, out httpRequestTimeoutSeconds))
            {
                httpRequestTimeoutSeconds = 100;
            }

            using (var httpClientHandler = HostContext.CreateHttpClientHandler())
            using (var httpClient = new HttpClient(httpClientHandler) { Timeout = new TimeSpan(0, 0, httpRequestTimeoutSeconds) })
            {
                errorMessage = string.Empty;
                Task<HttpResponseMessage> sendAsyncTask = httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
                HttpResponseMessage response = sendAsyncTask.GetAwaiter().GetResult();
                if (!response.IsSuccessStatusCode)
                {
                    errorMessage = response.StatusCode.ToString();
                    return default(T);
                }

                string result = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                return JsonConvert.DeserializeObject<T>(result);
            }
        }
    }

    [DataContract]
    public class GitHubRepository
    {
        [DataMember(EmitDefaultValue = false)]
        public int? Id { get; set; }

        [DataMember(EmitDefaultValue = false)]
        public string Name { get; set; }

        [DataMember(EmitDefaultValue = false)]
        public string Clone_url { get; set; }
    }
}


text:
'use strict';
goog.provide('functional.gles3.es3fFboInvalidateTests');
goog.require('framework.common.tcuImageCompare');
goog.require('framework.common.tcuRGBA');
goog.require('framework.common.tcuTestCase');
goog.require('framework.common.tcuTexture');
goog.require('framework.common.tcuTextureUtil');
goog.require('framework.delibs.debase.deMath');
goog.require('framework.opengl.gluShaderUtil');
goog.require('framework.opengl.gluTextureUtil');
goog.require('framework.referencerenderer.rrUtil');
goog.require('functional.gles3.es3fFboTestCase');
goog.require('functional.gles3.es3fFboTestUtil');

goog.scope(function() {
var es3fFboInvalidateTests = functional.gles3.es3fFboInvalidateTests;
var tcuTestCase = framework.common.tcuTestCase;
var es3fFboTestCase = functional.gles3.es3fFboTestCase;
var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
var rrUtil = framework.referencerenderer.rrUtil;
var gluShaderUtil = framework.opengl.gluShaderUtil;
var gluTextureUtil = framework.opengl.gluTextureUtil;
var tcuTexture = framework.common.tcuTexture;
var tcuTextureUtil = framework.common.tcuTextureUtil;
var deMath = framework.delibs.debase.deMath;
var tcuRGBA = framework.common.tcuRGBA;
var tcuImageCompare = framework.common.tcuImageCompare;

/** @type {WebGL2RenderingContext} */ var gl;

var setParentClass = function(child, parent) {
    child.prototype = Object.create(parent.prototype);
    child.prototype.constructor = child;
};

var getDefaultFBDiscardAttachments = function(discardBufferBits) {
    var attachments = [];

    if (discardBufferBits & gl.COLOR_BUFFER_BIT)
        attachments.push(gl.COLOR);

    if (discardBufferBits & gl.DEPTH_BUFFER_BIT)
        attachments.push(gl.DEPTH);

    if (discardBufferBits & gl.STENCIL_BUFFER_BIT)
        attachments.push(gl.STENCIL);

    return attachments;
};

var getFBODiscardAttachments = function(discardBufferBits) {
    var attachments = [];

    if (discardBufferBits & gl.COLOR_BUFFER_BIT)
        attachments.push(gl.COLOR_ATTACHMENT0);

    // \note DEPTH_STENCIL_ATTACHMENT is allowed when discarding FBO, but not with default FB
    if ((discardBufferBits & (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) == (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT))
        attachments.push(gl.DEPTH_STENCIL_ATTACHMENT);
    else if (discardBufferBits & gl.DEPTH_BUFFER_BIT)
        attachments.push(gl.DEPTH_ATTACHMENT);
    else if (discardBufferBits & gl.STENCIL_BUFFER_BIT)
        attachments.push(gl.STENCIL_ATTACHMENT);

    return attachments;
};

var getCompatibleColorFormat = function() {
    var redBits = gl.getParameter(gl.RED_BITS);
    var greenBits = gl.getParameter(gl.GREEN_BITS);
    var blueBits = gl.getParameter(gl.BLUE_BITS);
    var alphaBits = gl.getParameter(gl.ALPHA_BITS);
    switch ('' + redBits + greenBits + blueBits + alphaBits) {
        case '8888' : return gl.RGBA8;
        case '8880' : return gl.RGB8;
        default:
            throw new Error('Unexpected bit depth');
    }
};

var getCompatibleDepthStencilFormat = function() {
    var depthBits = /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS));
    var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
    var hasDepth = depthBits > 0;
    var hasStencil = stencilBits > 0;

    if (!hasDepth || !hasStencil || (stencilBits != 8))
        return gl.NONE;

    if (depthBits == 32)
        return gl.DEPTH32F_STENCIL8;
    else if (depthBits == 24)
        return gl.DEPTH24_STENCIL8;
    else
        return gl.NONE;
};

var hasAttachment = function(attachments, attachment) {
    return attachments.indexOf(attachment) >= 0;
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} buffers
 * @param {number=} target
 */
es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase = function(name, desc, buffers, target) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_buffers = buffers;
    this.m_fboTarget = target || gl.FRAMEBUFFER;
};

setParentClass(es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var attachments = getDefaultFBDiscardAttachments(this.m_buffers);

    var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var program = ctx.createProgram(shader);
    shader.setColor(ctx, program, [1, 0, 0, 1]);
    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
    ctx.invalidateFramebuffer(this.m_fboTarget, attachments);

    if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
        // Color was not preserved - fill with green.
        ctx.disable(gl.DEPTH_TEST);
        ctx.disable(gl.STENCIL_TEST);

        shader.setColor(ctx, program, [0, 1, 0, 1]);
        rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);

        ctx.enable(gl.DEPTH_TEST);
        ctx.enable(gl.STENCIL_TEST);
    }

    if ((this.m_buffers & gl.DEPTH_BUFFER_BIT) != 0) {
        // Depth was not preserved.
        ctx.depthFunc(gl.ALWAYS);
    }

    if ((this.m_buffers & gl.STENCIL_BUFFER_BIT) == 0) {
        // Stencil was preserved.
        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    }

    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);

    shader.setColor(ctx, program, [0, 0, 1, 1]);
    rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    dst.readViewport(ctx);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} buffers
 */
es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase = function(name, desc, buffers) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_buffers = buffers;
};

setParentClass(es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var attachments = getDefaultFBDiscardAttachments(this.m_buffers);

    var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var program = ctx.createProgram(shader);

    /** @type {es3fFboTestUtil.Texture2DShader} */
    var texShader = new es3fFboTestUtil.Texture2DShader(
        [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);

    /** @type {es3fFboTestUtil.GradientShader} */
    var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);

    var texShaderID = ctx.createProgram(texShader);
    var gradShaderID = ctx.createProgram(gradShader);
    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    // Create fbo.
    var fbo = ctx.createFramebuffer();
    var tex = ctx.createTexture();
    ctx.bindTexture(gl.TEXTURE_2D, tex);
    ctx.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, this.getWidth(), this.getHeight(), 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
    ctx.bindTexture(gl.TEXTURE_2D, null);
    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    shader.setColor(ctx, program, [1, 0, 0, 1]);
    rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);

    ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);

    // Switch to fbo and render gradient into it.
    ctx.disable(gl.DEPTH_TEST);
    ctx.disable(gl.STENCIL_TEST);
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);

    gradShader.setGradient(ctx, gradShaderID, [0, 0, 0, 0], [1, 1, 1, 1]);
    rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
    // Restore default fbo.
    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);

    if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
        // Color was not preserved - fill with green.
        shader.setColor(ctx, program, [0, 1, 0, 1]);
        rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    }

    if ((this.m_buffers & gl.DEPTH_BUFFER_BIT) != 0) {
        // Depth was not preserved.
        ctx.depthFunc(gl.ALWAYS);
    }

    if ((this.m_buffers & gl.STENCIL_BUFFER_BIT) == 0) {
        // Stencil was preserved.
        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    }

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);
    ctx.bindTexture(gl.TEXTURE_2D, tex);

    texShader.setUniforms(ctx, texShaderID);
    rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);

    dst.readViewport(ctx);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} buffers
 * @param {number=} target
 */
es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase = function(name, desc, buffers, target) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_buffers = buffers;
    this.m_fboTarget = target || gl.FRAMEBUFFER;
};

setParentClass(es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var invalidateX = this.getWidth() / 4;
    var invalidateY = this.getHeight() / 4;
    var invalidateW = this.getWidth() / 2;
    var invalidateH = this.getHeight() / 2;
    var attachments = getDefaultFBDiscardAttachments(this.m_buffers);

    var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var program = ctx.createProgram(shader);
    shader.setColor(ctx, program, [1, 0, 0, 1]);
    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
    ctx.invalidateSubFramebuffer(this.m_fboTarget, attachments, invalidateX, invalidateY, invalidateW, invalidateH);

    // Clear invalidated buffers.
    ctx.clearColor(0, 1, 0, 1);
    ctx.clearStencil(1);
    ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
    ctx.enable(gl.SCISSOR_TEST);
    ctx.clear(this.m_buffers);
    ctx.disable(gl.SCISSOR_TEST);

    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);

    shader.setColor(ctx, program, [0, 0, 1, 1]);
    rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    dst.readViewport(ctx);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} buffers
 */
es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase = function(name, desc, buffers) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_buffers = buffers;
};

setParentClass(es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
    var invalidateX = this.getWidth() / 4;
    var invalidateY = this.getHeight() / 4;
    var invalidateW = this.getWidth() / 2;
    var invalidateH = this.getHeight() / 2;

    var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var program = ctx.createProgram(shader);

    /** @type {es3fFboTestUtil.Texture2DShader} */
    var texShader = new es3fFboTestUtil.Texture2DShader(
        [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);

    /** @type {es3fFboTestUtil.GradientShader} */
    var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);

    var texShaderID = ctx.createProgram(texShader);
    var gradShaderID = ctx.createProgram(gradShader);
    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    // Create fbo.
    var fbo = ctx.createFramebuffer();
    var tex = ctx.createTexture();
    ctx.bindTexture(gl.TEXTURE_2D, tex);
    ctx.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, this.getWidth(), this.getHeight(), 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
    ctx.bindTexture(gl.TEXTURE_2D, null);
    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    shader.setColor(ctx, program, [1, 0, 0, 1]);
    rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);

    ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);

    // Switch to fbo and render gradient into it.
    ctx.disable(gl.DEPTH_TEST);
    ctx.disable(gl.STENCIL_TEST);
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);

    gradShader.setGradient(ctx, gradShaderID, [0, 0, 0, 0], [1, 1, 1, 1]);
    rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
    // Restore default fbo.
    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);

    if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
        // Color was not preserved - fill with green.
        shader.setColor(ctx, program, [0, 1, 0, 1]);
        rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
    }

    // Clear invalidated buffers.
    ctx.clearColor(0, 1, 0, 1);
    ctx.clearStencil(1);
    ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
    ctx.enable(gl.SCISSOR_TEST);
    ctx.clear(this.m_buffers);
    ctx.disable(gl.SCISSOR_TEST);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);
    ctx.bindTexture(gl.TEXTURE_2D, tex);

    texShader.setUniforms(ctx, texShaderID);
    rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);

    dst.readViewport(ctx);
    ctx.disable(gl.DEPTH_TEST);
    ctx.disable(gl.STENCIL_TEST);
    ctx.disable(gl.BLEND);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} colorFmt
 * @param {number} depthStencilFmt
 * @param {number} invalidateBuffers
 */
es3fFboInvalidateTests.InvalidateFboRenderCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_colorFmt = colorFmt;
    this.m_depthStencilFmt = depthStencilFmt;
    this.m_invalidateBuffers = invalidateBuffers;
};

setParentClass(es3fFboInvalidateTests.InvalidateFboRenderCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateFboRenderCase.prototype.preCheck = function() {
    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    return true; // No exception thrown
};

es3fFboInvalidateTests.InvalidateFboRenderCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var cBias = colorFmtInfo.valueMin;
    var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    var flatShaderID = ctx.createProgram(flatShader);

    // Create fbo.
    var colorRbo = ctx.createRenderbuffer();
    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
    ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_colorFmt, this.getWidth(), this.getHeight());

    if (this.m_depthStencilFmt != gl.NONE) {
        var depthStencilRbo = ctx.createRenderbuffer();
        ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
        ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_depthStencilFmt, this.getWidth(), this.getHeight());
    }

    var fbo = ctx.createFramebuffer();
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);

    if (depth)
        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    if (stencil)
        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);

    ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);

    if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
        // Color was not preserved - fill with green.
        ctx.disable(gl.DEPTH_TEST);
        ctx.disable(gl.STENCIL_TEST);

        flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));
        rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);

        ctx.enable(gl.DEPTH_TEST);
        ctx.enable(gl.STENCIL_TEST);
    }

    if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
        // Depth was not preserved.
        ctx.depthFunc(gl.ALWAYS);
    }

    if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
        // Stencil was preserved.
        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    }

    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);

    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);

    es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} colorFmt
 * @param {number} depthStencilFmt
 * @param {number} invalidateBuffers
 */
es3fFboInvalidateTests.InvalidateFboUnbindReadCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_colorFmt = colorFmt;
    this.m_depthStencilFmt = depthStencilFmt;
    this.m_invalidateBuffers = invalidateBuffers;
};

setParentClass(es3fFboInvalidateTests.InvalidateFboUnbindReadCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateFboUnbindReadCase.prototype.preCheck = function() {
    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    return true; // No exception thrown
};

es3fFboInvalidateTests.InvalidateFboUnbindReadCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    // Create fbo.
    var transferFmt = gluTextureUtil.getTransferFormat(colorFmt);
    var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var gradShaderID = ctx.createProgram(gradShader);

    var colorTex = ctx.createTexture();
    ctx.bindTexture(gl.TEXTURE_2D, colorTex);
    ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_colorFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

    if (this.m_depthStencilFmt != gl.NONE) {
        transferFmt = gluTextureUtil.getTransferFormat(depthStencilFmt);

        var depthStencilTex = ctx.createTexture();
        ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
        ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_depthStencilFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
        ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    }

    var fbo = ctx.createFramebuffer();
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);

    if (depth)
        ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);

    if (stencil)
        ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);

    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    gradShader.setGradient(ctx, gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
    rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);

    ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);

    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
    ctx.disable(gl.DEPTH_TEST);
    ctx.disable(gl.STENCIL_TEST);

    if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
        // Render color.
        /** @type {es3fFboTestUtil.Texture2DShader} */
        var texShader = new es3fFboTestUtil.Texture2DShader(
            [gluTextureUtil.getSampler2DType(colorFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
        var texShaderID = ctx.createProgram(texShader);

        texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
        texShader.setUniforms(ctx, texShaderID);

        ctx.bindTexture(gl.TEXTURE_2D, colorTex);
        rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    } else {
        // Render depth.
        texShader = new es3fFboTestUtil.Texture2DShader(
            [gluTextureUtil.getSampler2DType(depthStencilFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
        texShaderID = ctx.createProgram(texShader);

        texShader.setUniforms(ctx, texShaderID);

        ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
        rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    }

    dst.readViewport(ctx);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} numSamples
 * @param {number} invalidateBuffers
 */
es3fFboInvalidateTests.InvalidateFboUnbindBlitCase = function(name, desc, numSamples, invalidateBuffers) {
// \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
//       behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
//       source and destination rectangles must match when multisampling.
    es3fFboTestCase.FboTestCase.call(this, name, desc, numSamples > 0);
    this.m_numSamples = numSamples;
    this.m_colorFmt = getCompatibleColorFormat();
    this.m_depthStencilFmt = getCompatibleDepthStencilFormat();
    this.m_invalidateBuffers = invalidateBuffers;
};

setParentClass(es3fFboInvalidateTests.InvalidateFboUnbindBlitCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateFboUnbindBlitCase.prototype.preCheck = function() {
    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    return true; // No exception thrown
};

es3fFboInvalidateTests.InvalidateFboUnbindBlitCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var quadSizePixels = [this.m_numSamples == 0 ? this.getWidth() : Math.min(128, this.getWidth()),
                                                     this.m_numSamples == 0 ? this.getHeight() : Math.min(128, this.getHeight())];
    var quadNDCLeftBottomXY = [-1, -1];
    var quadNDCSize = [2 * quadSizePixels[0] / this.getWidth(), 2 * quadSizePixels[1] / this.getHeight()];
    var quadNDCRightTopXY = deMath.add(quadNDCLeftBottomXY, quadNDCSize);
    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    var flatShaderID = ctx.createProgram(flatShader);

    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    // Create fbo.
    var colorRbo = ctx.createRenderbuffer();
    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
    ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_colorFmt, quadSizePixels[0], quadSizePixels[1]);

    if (this.m_depthStencilFmt != gl.NONE) {
        var depthStencilRbo = ctx.createRenderbuffer();
        ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
        ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_depthStencilFmt, quadSizePixels[0], quadSizePixels[1]);
    }

    var fbo = ctx.createFramebuffer();
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);

    if (depth)
        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    if (stencil)
        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    flatShader.setColor(ctx, flatShaderID, [1, 0, 0, 1]);
    rrUtil.drawQuad(ctx, flatShaderID,
        [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], -1],
        [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 1]);

    ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);

    // Set default framebuffer as draw framebuffer and blit preserved buffers.
    ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    ctx.blitFramebuffer(0, 0, quadSizePixels[0], quadSizePixels[1],
                         0, 0, quadSizePixels[0], quadSizePixels[1],
                         (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) & ~this.m_invalidateBuffers, gl.NEAREST);
    ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);

    if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
        // Color was not preserved - fill with green.
        ctx.disable(gl.DEPTH_TEST);
        ctx.disable(gl.STENCIL_TEST);

        flatShader.setColor(ctx, flatShaderID, [0, 1, 0, 1]);
        rrUtil.drawQuad(ctx, flatShaderID,
            [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
            [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);

        ctx.enable(gl.DEPTH_TEST);
        ctx.enable(gl.STENCIL_TEST);
    }

    if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
        // Depth was not preserved.
        ctx.depthFunc(gl.ALWAYS);
    }

    if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
        // Stencil was preserved.
        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    }

    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);

    flatShader.setColor(ctx, flatShaderID, [0, 0, 1, 1]);
    rrUtil.drawQuad(ctx, flatShaderID,
        [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
        [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);

    dst.readViewport(ctx, [0, 0, quadSizePixels[0], quadSizePixels[1]]);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} colorFmt
 * @param {number} depthStencilFmt
 * @param {number} invalidateBuffers
 */
es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_colorFmt = colorFmt;
    this.m_depthStencilFmt = depthStencilFmt;
    this.m_invalidateBuffers = invalidateBuffers;
};

setParentClass(es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.preCheck = function() {
    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    return true; // No exception thrown
};

es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.compare = function(reference, result) {
    var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_colorFmt), new tcuRGBA.RGBA([12, 12, 12, 12]));
    return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold);
};

es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    // Create fbo.
    var transferFmt = gluTextureUtil.getTransferFormat(colorFmt);
    var gradShader = new es3fFboTestUtil.GradientShader(es3fFboTestUtil.getFragmentOutputType(colorFmt));
    var gradShaderID = ctx.createProgram(gradShader);
    var invalidateX = 0;
    var invalidateY = 0;
    var invalidateW = this.getWidth() / 2;
    var invalidateH = this.getHeight();
    var readX = invalidateW;
    var readY = 0;
    var readW = this.getWidth() / 2;
    var readH = this.getHeight();

    var colorTex = ctx.createTexture();
    ctx.bindTexture(gl.TEXTURE_2D, colorTex);
    ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_colorFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

    if (this.m_depthStencilFmt != gl.NONE) {
        transferFmt = gluTextureUtil.getTransferFormat(depthStencilFmt);

        var depthStencilTex = ctx.createTexture();
        ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
        ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_depthStencilFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
        ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    }

    var fbo = ctx.createFramebuffer();
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);

    if (depth)
        ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);

    if (stencil)
        ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);

    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    this.clearColorBuffer(colorFmt, [0.0, 0.0, 0.0, 1.0]);
    ctx.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    gradShader.setGradient(ctx, gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
    rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);

    ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);

    ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
    ctx.disable(gl.DEPTH_TEST);
    ctx.disable(gl.STENCIL_TEST);

    ctx.clearColor(0.25, 0.5, 0.75, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    // Limit read area using scissor.
    ctx.scissor(readX, readY, readW, readH);
    ctx.enable(gl.SCISSOR_TEST);

    if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
        // Render color.
        /** @type {es3fFboTestUtil.Texture2DShader} */
        var texShader = new es3fFboTestUtil.Texture2DShader(
            [gluTextureUtil.getSampler2DType(colorFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
        var texShaderID = ctx.createProgram(texShader);

        texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
        texShader.setUniforms(ctx, texShaderID);

        ctx.bindTexture(gl.TEXTURE_2D, colorTex);
        rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    } else {
        // Render depth.
        texShader = new es3fFboTestUtil.Texture2DShader(
            [gluTextureUtil.getSampler2DType(depthStencilFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
        texShaderID = ctx.createProgram(texShader);

        texShader.setUniforms(ctx, texShaderID);

        ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
        rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
    }

    dst.readViewport(ctx);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} colorFmt
 * @param {number} depthStencilFmt
 * @param {number} invalidateBuffers
 */
es3fFboInvalidateTests.InvalidateSubFboRenderCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_colorFmt = colorFmt;
    this.m_depthStencilFmt = depthStencilFmt;
    this.m_invalidateBuffers = invalidateBuffers;
};

setParentClass(es3fFboInvalidateTests.InvalidateSubFboRenderCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateSubFboRenderCase.prototype.preCheck = function() {
    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    return true; // No exception thrown
};

es3fFboInvalidateTests.InvalidateSubFboRenderCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var cBias = colorFmtInfo.valueMin;
    var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    var flatShaderID = ctx.createProgram(flatShader);
    var invalidateX = this.getWidth() / 4;
    var invalidateY = this.getHeight() / 4;
    var invalidateW = this.getWidth() / 2;
    var invalidateH = this.getHeight() / 2;

    // Create fbo.
    var colorRbo = ctx.createRenderbuffer();
    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
    ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_colorFmt, this.getWidth(), this.getHeight());

    if (this.m_depthStencilFmt != gl.NONE) {
        var depthStencilRbo = ctx.createRenderbuffer();
        ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
        ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_depthStencilFmt, this.getWidth(), this.getHeight());
    }

    var fbo = ctx.createFramebuffer();
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);

    if (depth)
        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    if (stencil)
        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    ctx.clearBufferfv(gl.COLOR, 0, deMath.add(deMath.multiply([0, 0, 0, 1], cScale), cBias));
    ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);

    ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);

    // Clear invalidated buffers.
    ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
    ctx.enable(gl.SCISSOR_TEST);

    if (this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT)
        ctx.clearBufferfv(gl.COLOR, 0, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));

    ctx.clear(this.m_invalidateBuffers & ~gl.COLOR_BUFFER_BIT);
    ctx.disable(gl.SCISSOR_TEST);

    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);

    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);

    es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} numSamples
 * @param {number} invalidateBuffers
 */
es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase = function(name, desc, numSamples, invalidateBuffers) {
// \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
//       behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
//       source and destination rectangles must match when multisampling.
    es3fFboTestCase.FboTestCase.call(this, name, desc, numSamples > 0);
    this.m_numSamples = numSamples;
    this.m_colorFmt = getCompatibleColorFormat();
    this.m_depthStencilFmt = getCompatibleDepthStencilFormat();
    this.m_invalidateBuffers = invalidateBuffers;
};

setParentClass(es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase.prototype.preCheck = function() {
    if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
    if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
    return true; // No exception thrown
};

es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var quadSizePixels = [this.m_numSamples == 0 ? this.getWidth() : Math.min(128, this.getWidth()),
                                                     this.m_numSamples == 0 ? this.getHeight() : Math.min(128, this.getHeight())];
    var quadNDCLeftBottomXY = [-1, -1];
    var quadNDCSize = [2 * quadSizePixels[0] / this.getWidth(), 2 * quadSizePixels[1] / this.getHeight()];
    var quadNDCRightTopXY = deMath.add(quadNDCLeftBottomXY, quadNDCSize);
    var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
    var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
    var flatShaderID = ctx.createProgram(flatShader);
    var invalidateX = 0;
    var invalidateY = 0;
    var invalidateW = quadSizePixels[0] / 2;
    var invalidateH = quadSizePixels[1];
    var blitX0 = invalidateW;
    var blitY0 = 0;
    var blitX1 = blitX0 + quadSizePixels[0] / 2;
    var blitY1 = blitY0 + quadSizePixels[1];

    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    // Create fbo.
    var colorRbo = ctx.createRenderbuffer();
    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
    ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_colorFmt, quadSizePixels[0], quadSizePixels[1]);

    if (this.m_depthStencilFmt != gl.NONE) {
        var depthStencilRbo = ctx.createRenderbuffer();
        ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
        ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_depthStencilFmt, quadSizePixels[0], quadSizePixels[1]);
    }

    var fbo = ctx.createFramebuffer();
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);

    if (depth)
        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    if (stencil)
        ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    flatShader.setColor(ctx, flatShaderID, [1, 0, 0, 1]);
    rrUtil.drawQuad(ctx, flatShaderID,
        [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], -1],
        [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 1]);

    ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);

    // Set default framebuffer as draw framebuffer and blit preserved buffers.
    ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    ctx.blitFramebuffer(blitX0, blitY0, blitX1, blitY1, blitX0, blitY0, blitX1, blitY1,
                         (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) & ~this.m_invalidateBuffers, gl.NEAREST);
    ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);

    if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
        // Color was not preserved - fill with green.
        ctx.disable(gl.DEPTH_TEST);
        ctx.disable(gl.STENCIL_TEST);

        flatShader.setColor(ctx, flatShaderID, [0, 1, 0, 1]);
        rrUtil.drawQuad(ctx, flatShaderID,
            [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
            [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);

        ctx.enable(gl.DEPTH_TEST);
        ctx.enable(gl.STENCIL_TEST);
    }

    if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
        // Depth was not preserved.
        ctx.depthFunc(gl.ALWAYS);
    }

    if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
        // Stencil was preserved.
        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    }

    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);

    flatShader.setColor(ctx, flatShaderID, [0, 0, 1, 1]);
    rrUtil.drawQuad(ctx, flatShaderID,
        [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
        [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);

    dst.readViewport(ctx, [0, 0, quadSizePixels[0], quadSizePixels[1]]);
};

/**
 * @constructor
 * @extends {es3fFboTestCase.FboTestCase}
 * @param {string} name
 * @param {string} desc
 * @param {number} boundTarget
 * @param {number} invalidateTarget
 * @param {Array<number>} invalidateAttachments
 */
es3fFboInvalidateTests.InvalidateFboTargetCase = function(name, desc, boundTarget, invalidateTarget, invalidateAttachments) {
    es3fFboTestCase.FboTestCase.call(this, name, desc);
    this.m_boundTarget = boundTarget;
    this.m_invalidateTarget = invalidateTarget;
    this.m_invalidateAttachments = invalidateAttachments;
};

setParentClass(es3fFboInvalidateTests.InvalidateFboTargetCase, es3fFboTestCase.FboTestCase);

es3fFboInvalidateTests.InvalidateFboTargetCase.prototype.render = function(dst) {
    var ctx = this.getCurrentContext();
    var colorFormat = gl.RGBA8;
    var depthStencilFormat = gl.DEPTH24_STENCIL8;
    var colorFmt = gluTextureUtil.mapGLInternalFormat(colorFormat);
    var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
    var cBias = colorFmtInfo.valueMin;
    var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
    var isDiscarded = (this.m_boundTarget == gl.FRAMEBUFFER) ||
                                    (this.m_invalidateTarget == gl.FRAMEBUFFER && this.m_boundTarget == gl.DRAW_FRAMEBUFFER) ||
                                    (this.m_invalidateTarget == this.m_boundTarget);
    var isColorDiscarded = isDiscarded && hasAttachment(this.m_invalidateAttachments, gl.COLOR_ATTACHMENT0);
    var isDepthDiscarded = isDiscarded && (hasAttachment(this.m_invalidateAttachments, gl.DEPTH_ATTACHMENT) || hasAttachment(this.m_invalidateAttachments, gl.DEPTH_STENCIL_ATTACHMENT));
    var isStencilDiscarded = isDiscarded && (hasAttachment(this.m_invalidateAttachments, gl.STENCIL_ATTACHMENT) || hasAttachment(this.m_invalidateAttachments, gl.DEPTH_STENCIL_ATTACHMENT));

    var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
    var flatShaderID = ctx.createProgram(flatShader);

    // Create fbo.
    var colorRbo = ctx.createRenderbuffer();
    ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
    ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.getWidth(), this.getHeight());

    var depthStencilRbo = ctx.createRenderbuffer();
    ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
    ctx.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, this.getWidth(), this.getHeight());

    var fbo = ctx.createFramebuffer();
    ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
    ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);

    this.checkFramebufferStatus(gl.FRAMEBUFFER);

    ctx.clearColor(0, 0, 0, 1);
    ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);

    ctx.enable(gl.DEPTH_TEST);
    ctx.enable(gl.STENCIL_TEST);
    ctx.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
    ctx.stencilFunc(gl.ALWAYS, 1, 0xff);

    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);

    // Bound FBO to test target and default to other
    if (this.m_boundTarget != gl.FRAMEBUFFER) {
        // Dummy fbo is used as complemeting target (read when discarding draw for example).
        // \note Framework takes care of deleting objects at the end of test case.
        var dummyTarget = this.m_boundTarget == gl.DRAW_FRAMEBUFFER ? gl.READ_FRAMEBUFFER : gl.DRAW_FRAMEBUFFER;

        var dummyColorRbo = ctx.createRenderbuffer();
        ctx.bindRenderbuffer(gl.RENDERBUFFER, dummyColorRbo);
        ctx.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 64, 64);
        var dummyFbo = ctx.createFramebuffer();
        ctx.bindFramebuffer(dummyTarget, dummyFbo);
        ctx.framebufferRenderbuffer(dummyTarget, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dummyColorRbo);

        ctx.bindFramebuffer(this.m_boundTarget, fbo);
    }

    ctx.invalidateFramebuffer(this.m_invalidateTarget, this.m_invalidateAttachments);

    if (this.m_boundTarget != gl.FRAMEBUFFER)
        ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);

    if (isColorDiscarded) {
        // Color was not preserved - fill with green.
        ctx.disable(gl.DEPTH_TEST);
        ctx.disable(gl.STENCIL_TEST);

        flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));
        rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);

        ctx.enable(gl.DEPTH_TEST);
        ctx.enable(gl.STENCIL_TEST);
    }

    if (isDepthDiscarded) {
        // Depth was not preserved.
        ctx.depthFunc(gl.ALWAYS);
    }

    if (!isStencilDiscarded) {
        // Stencil was preserved.
        ctx.stencilFunc(gl.EQUAL, 1, 0xff);
    }

    ctx.enable(gl.BLEND);
    ctx.blendFunc(gl.ONE, gl.ONE);
    ctx.blendEquation(gl.FUNC_ADD);

    flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
    rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);

    es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
};

/**
* @constructor
* @extends {tcuTestCase.DeqpTest}
*/
es3fFboInvalidateTests.FboInvalidateTests = function() {
    tcuTestCase.DeqpTest.call(this, 'invalidate', 'Framebuffer invalidate tests');
};

es3fFboInvalidateTests.FboInvalidateTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
es3fFboInvalidateTests.FboInvalidateTests.prototype.constructor = es3fFboInvalidateTests.FboInvalidateTests;

es3fFboInvalidateTests.FboInvalidateTests.prototype.init = function() {
    var defaultFbGroup = new tcuTestCase.DeqpTest('default', 'Default framebuffer invalidate tests');
    this.addChild(defaultFbGroup);

    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_none', 'Invalidating no framebuffers (ref)', 0));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_color', 'Rendering after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_depth', 'Rendering after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_stencil', 'Rendering after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_depth_stencil', 'Rendering after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_all', 'Rendering after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_color', 'Binding fbo after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_depth', 'Binding fbo after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_stencil', 'Binding fbo after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_depth_stencil', 'Binding fbo after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_all', 'Binding fbo after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_color', 'Rendering after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_depth', 'Rendering after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_stencil', 'Rendering after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_depth_stencil', 'Rendering after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_all', 'Rendering after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_color', 'Binding fbo after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_depth', 'Binding fbo after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_stencil', 'Binding fbo after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_depth_stencil', 'Binding fbo after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_all', 'Binding fbo after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('draw_framebuffer_color', 'Invalidating gl.COLOR in gl.DRAW_FRAMEBUFFER', gl.COLOR_BUFFER_BIT, gl.DRAW_FRAMEBUFFER));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('draw_framebuffer_all', 'Invalidating all in gl.DRAW_FRAMEBUFFER', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.DRAW_FRAMEBUFFER));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('read_framebuffer_color', 'Invalidating gl.COLOR in gl.READ_FRAMEBUFFER', gl.COLOR_BUFFER_BIT, gl.READ_FRAMEBUFFER));
    defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('read_framebuffer_all', 'Invalidating all in gl.READ_FRAMEBUFFER', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.READ_FRAMEBUFFER));

    // invalidate.whole.
    var wholeFboGroup = new tcuTestCase.DeqpTest('whole', 'Invalidating whole framebuffer object');
    this.addChild(wholeFboGroup);
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_none', '', gl.RGBA8, gl.DEPTH24_STENCIL8, 0));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_all', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));

    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_color_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));

    if (getCompatibleDepthStencilFormat() !== gl.NONE) {
        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_color', '', 0, gl.COLOR_BUFFER_BIT));
        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_depth', '', 0, gl.DEPTH_BUFFER_BIT));
        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_stencil', '', 0, gl.STENCIL_BUFFER_BIT));
        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_depth_stencil', '', 0, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_color', '', 4, gl.COLOR_BUFFER_BIT));
        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_depth', '', 4, gl.DEPTH_BUFFER_BIT));
        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_stencil', '', 4, gl.STENCIL_BUFFER_BIT));
        wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_depth_stencil', '', 4, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    }

    // invalidate.sub.
    var subFboGroup = new tcuTestCase.DeqpTest('sub', 'Invalidating subsection of framebuffer object');
    this.addChild(subFboGroup);
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_none', '', gl.RGBA8, gl.DEPTH24_STENCIL8, 0));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_all', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));

    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_color_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));

    if (getCompatibleDepthStencilFormat() !== gl.NONE) {
        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_color', '', 0, gl.COLOR_BUFFER_BIT));
        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_depth', '', 0, gl.DEPTH_BUFFER_BIT));
        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_stencil', '', 0, gl.STENCIL_BUFFER_BIT));
        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_depth_stencil', '', 0, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_color', '', 4, gl.COLOR_BUFFER_BIT));
        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_depth', '', 4, gl.DEPTH_BUFFER_BIT));
        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_stencil', '', 4, gl.STENCIL_BUFFER_BIT));
        subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_depth_stencil', '', 4, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
    }
    // invalidate.format.
    var numFormatSubGroups = 3;
    var formatGroup = [];
    for (var ii = 0; ii < numFormatSubGroups; ++ii) {
        formatGroup[ii] = new tcuTestCase.DeqpTest('format', 'Invalidating framebuffers with selected formats');
        this.addChild(formatGroup[ii]);
    }
    // Color buffer formats.
    var colorFormats = [
        // RGBA formats
        gl.RGBA32I,
        gl.RGBA32UI,
        gl.RGBA16I,
        gl.RGBA16UI,
        gl.RGBA8,
        gl.RGBA8I,
        gl.RGBA8UI,
        gl.SRGB8_ALPHA8,
        gl.RGB10_A2,
        gl.RGB10_A2UI,
        gl.RGBA4,
        gl.RGB5_A1,

        // RGB formats
        gl.RGB8,
        gl.RGB565,

        // RG formats
        gl.RG32I,
        gl.RG32UI,
        gl.RG16I,
        gl.RG16UI,
        gl.RG8,
        gl.RG8I,
        gl.RG8UI,

        // R formats
        gl.R32I,
        gl.R32UI,
        gl.R16I,
        gl.R16UI,
        gl.R8,
        gl.R8I,
        gl.R8UI,

        // gl.EXT_color_buffer_float
        gl.RGBA32F,
        gl.RGBA16F,
        gl.R11F_G11F_B10F,
        gl.RG32F,
        gl.RG16F,
        gl.R32F,
        gl.R16F
    ];

    // Depth/stencilbuffer formats.
    var depthStencilFormats = [
        gl.DEPTH_COMPONENT32F,
        gl.DEPTH_COMPONENT24,
        gl.DEPTH_COMPONENT16,
        gl.DEPTH32F_STENCIL8,
        gl.DEPTH24_STENCIL8,
        gl.STENCIL_INDEX8
    ];

    // Colorbuffer tests use invalidate, unbind, read test.
    for (var ndx = 0; ndx < colorFormats.length; ndx++)
        formatGroup[ndx % numFormatSubGroups].addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase(es3fFboTestUtil.getFormatName(colorFormats[ndx]), '', colorFormats[ndx], gl.NONE, gl.COLOR_BUFFER_BIT));

    // Depth/stencilbuffer tests use invalidate, render test.
    for (var ndx = 0; ndx < depthStencilFormats.length; ndx++)
        formatGroup[ndx % numFormatSubGroups].addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase(es3fFboTestUtil.getFormatName(depthStencilFormats[ndx]), '', gl.RGBA8, depthStencilFormats[ndx], gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));

    // invalidate.target
    var targetGroup = new tcuTestCase.DeqpTest('target', 'Invalidate target');
    this.addChild(targetGroup);

    var s_targetCases = [
        ['framebuffer_framebuffer', gl.FRAMEBUFFER, gl.FRAMEBUFFER],
        ['framebuffer_read_framebuffer', gl.FRAMEBUFFER, gl.READ_FRAMEBUFFER],
        ['framebuffer_draw_framebuffer', gl.FRAMEBUFFER, gl.DRAW_FRAMEBUFFER],
        ['read_framebuffer_framebuffer', gl.READ_FRAMEBUFFER, gl.FRAMEBUFFER],
        ['read_framebuffer_read_framebuffer', gl.READ_FRAMEBUFFER, gl.READ_FRAMEBUFFER],
        ['read_framebuffer_draw_framebuffer', gl.READ_FRAMEBUFFER, gl.DRAW_FRAMEBUFFER],
        ['draw_framebuffer_framebuffer', gl.DRAW_FRAMEBUFFER, gl.FRAMEBUFFER],
        ['draw_framebuffer_read_framebuffer', gl.DRAW_FRAMEBUFFER, gl.READ_FRAMEBUFFER],
        ['draw_framebuffer_draw_framebuffer', gl.DRAW_FRAMEBUFFER, gl.DRAW_FRAMEBUFFER]
    ];

    var colorAttachment = [gl.COLOR_ATTACHMENT0];
    var depthStencilAttachment = [gl.DEPTH_STENCIL_ATTACHMENT];
    var allAttachments = [gl.COLOR_ATTACHMENT0, gl.DEPTH_ATTACHMENT, gl.STENCIL_ATTACHMENT];

    for (var caseNdx = 0; caseNdx < s_targetCases.length; caseNdx++) {
        var baseName = s_targetCases[caseNdx][0];
        var invalidateT = s_targetCases[caseNdx][1];
        var boundT = s_targetCases[caseNdx][1];

        targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_color', '', boundT, invalidateT, colorAttachment));
        targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_depth_stencil', '', boundT, invalidateT, depthStencilAttachment));
        targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_all', '', boundT, invalidateT, allAttachments));
    }

};

/**
* Run test
* @param {WebGL2RenderingContext} context
*/
es3fFboInvalidateTests.run = function(context, range) {
    gl = context;
    //Set up Test Root parameters
    var state = tcuTestCase.runner;
    state.setRoot(new es3fFboInvalidateTests.FboInvalidateTests());

    //Set up name and description of this test series.
    setCurrentTestName(state.testCases.fullName());
    description(state.testCases.getDescription());

    try {
        if (range)
            state.setRange(range);
        //Run test cases
        tcuTestCase.runTestCases();
    }
    catch (err) {
        testFailedOptions('Failed to es3fFboInvalidateTests.run tests', false);
        tcuTestCase.runner.terminate();
    }
};

});


text:
package org.exbin.bined.extended.color;

import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.exbin.bined.color.CodeAreaBasicColors;
import org.exbin.bined.color.CodeAreaColorGroup;
import org.exbin.bined.color.CodeAreaColorType;

/**
 * Enumeration of unprintable color types.
 *
 * @version 0.2.0 2018/11/29
 * @author ExBin Project (https://exbin.org)
 */
@ParametersAreNonnullByDefault
public enum CodeAreaUnprintablesColorType implements CodeAreaColorType {

    UNPRINTABLES_COLOR(CodeAreaBasicColors.TEXT_COLOR.getId(), ExtendedCodeAreaColorsGroup.UNPRINTABLES),
    UNPRINTABLES_BACKGROUND(CodeAreaBasicColors.TEXT_BACKGROUND.getId(), ExtendedCodeAreaColorsGroup.UNPRINTABLES);

    @Nonnull
    private final String typeId;
    @Nullable
    private final CodeAreaColorGroup group;

    private CodeAreaUnprintablesColorType(String typeId, @Nullable CodeAreaColorGroup group) {
        this.typeId = typeId;
        this.group = group;
    }

    @Nonnull
    @Override
    public String getId() {
        return typeId;
    }

    @Nonnull
    @Override
    public Optional<CodeAreaColorGroup> getGroup() {
        return Optional.ofNullable(group);
    }
}


text:
package org.zstack.header.storage.primary;

/**
 * Created by yaoning.li on 2020/08/24.
 */
public class PrimaryStorageConstants {
    public static final String LOCAL_STORAGE_TYPE = "LocalStorage";
}