text:
--beginvalidatingquery
	if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_DatabaseVersion]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    begin
            declare @ver int
            exec @ver=sp_DatabaseVersion
            if (@ver >= 7023)
				select 0, 'Already correct database version'
            else if (@ver = 7022)
                 select 1, 'Upgrading database'
            else
                 select -1, 'Invalid database version detected'
    end
    else
            select -1, 'Not an EPiServer database'
--endvalidatingquery

GO
PRINT N'Dropping [dbo].[tblPropertyDefinition].[IDX_tblPropertyDefinition_Name]...';

GO
DROP INDEX [IDX_tblPropertyDefinition_Name]
    ON [dbo].[tblPropertyDefinition];

GO
PRINT N'Altering [dbo].[tblPropertyDefinition]...';

GO
ALTER TABLE [dbo].[tblPropertyDefinition] ALTER COLUMN [Name] NVARCHAR (100) NOT NULL;

GO
PRINT N'Creating [dbo].[tblPropertyDefinition].[IDX_tblPropertyDefinition_Name]...';

GO
CREATE NONCLUSTERED INDEX [IDX_tblPropertyDefinition_Name]
    ON [dbo].[tblPropertyDefinition]([Name] ASC);

GO
PRINT N'Altering [dbo].[netPageDefinitionSave]...';

GO
ALTER PROCEDURE dbo.netPageDefinitionSave
(
	@PageDefinitionID      INT OUTPUT,
	@PageTypeID            INT,
	@Name                  NVARCHAR(100),
	@PageDefinitionTypeID  INT,
	@Required              BIT = NULL,
	@Advanced              INT = NULL,
	@Searchable            BIT = NULL,
	@DefaultValueType      INT = NULL,
	@EditCaption           NVARCHAR(255) = NULL,
	@HelpText              NVARCHAR(2000) = NULL,
	@ObjectProgID          NVARCHAR(255) = NULL,
	@LongStringSettings    INT = NULL,
	@SettingsID            UNIQUEIDENTIFIER = NULL,
	@FieldOrder            INT = NULL,
	@Type                  INT = NULL OUTPUT,
	@OldType               INT = NULL OUTPUT,
	@LanguageSpecific      INT = 0,
	@DisplayEditUI         BIT = NULL,
	@ExistsOnModel         BIT = 0
)
AS
BEGIN
	SELECT @OldType = tblPageDefinitionType.Property
	FROM tblPageDefinition
	INNER JOIN tblPageDefinitionType ON tblPageDefinitionType.pkID=tblPageDefinition.fkPageDefinitionTypeID
	WHERE tblPageDefinition.pkID=@PageDefinitionID

	SELECT @Type = Property FROM tblPageDefinitionType WHERE pkID=@PageDefinitionTypeID
	IF @Type IS NULL
		RAISERROR('Cannot find data type',16,1)
	IF @PageTypeID=0
		SET @PageTypeID = NULL

	IF @PageDefinitionID = 0 AND @ExistsOnModel = 1
	BEGIN
		SET @PageDefinitionID = ISNULL((SELECT pkID FROM tblPageDefinition where Name = @Name AND fkPageTypeID = @PageTypeID), @PageDefinitionID)
	END

	IF @PageDefinitionID=0
	BEGIN
		INSERT INTO tblPageDefinition
		(
			fkPageTypeID,
			fkPageDefinitionTypeID,
			Name,
			Property,
			Required,
			Advanced,
			Searchable,
			DefaultValueType,
			EditCaption,
			HelpText,
			ObjectProgID,
			LongStringSettings,
			SettingsID,
			FieldOrder,
			LanguageSpecific,
			DisplayEditUI,
			ExistsOnModel
		)
		VALUES
		(
			@PageTypeID,
			@PageDefinitionTypeID,
			@Name,
			@Type,
			@Required,
			@Advanced,
			@Searchable,
			@DefaultValueType,
			@EditCaption,
			@HelpText,
			@ObjectProgID,
			@LongStringSettings,
			@SettingsID,
			@FieldOrder,
			@LanguageSpecific,
			@DisplayEditUI,
			@ExistsOnModel
		)
		SET @PageDefinitionID =  SCOPE_IDENTITY()
	END
	ELSE
	BEGIN
		UPDATE tblPageDefinition SET
			Name 		= @Name,
			fkPageDefinitionTypeID	= @PageDefinitionTypeID,
			Property 	= @Type,
			Required 	= @Required,
			Advanced 	= @Advanced,
			Searchable 	= @Searchable,
			DefaultValueType = @DefaultValueType,
			EditCaption 	= @EditCaption,
			HelpText 	= @HelpText,
			ObjectProgID 	= @ObjectProgID,
			LongStringSettings = @LongStringSettings,
			SettingsID = @SettingsID,
			LanguageSpecific = @LanguageSpecific,
			FieldOrder = @FieldOrder,
			DisplayEditUI = @DisplayEditUI,
			ExistsOnModel = @ExistsOnModel
		WHERE pkID=@PageDefinitionID
	END
	DELETE FROM tblPropertyDefault WHERE fkPageDefinitionID=@PageDefinitionID
	IF @LanguageSpecific<3
	BEGIN
		/* NOTE: Here we take into consideration that language neutral dynamic properties are always stored on language
			with id 1 (which perhaps should be changed and in that case the special handling here could be removed). */
		IF @PageTypeID IS NULL
		BEGIN
			DELETE tblProperty
			FROM tblProperty
			INNER JOIN tblPage ON tblPage.pkID=tblProperty.fkPageID
			WHERE fkPageDefinitionID=@PageDefinitionID AND tblProperty.fkLanguageBranchID<>1
		END
		ELSE
		BEGIN
			DELETE tblProperty
			FROM tblProperty
			INNER JOIN tblPage ON tblPage.pkID=tblProperty.fkPageID
			WHERE fkPageDefinitionID=@PageDefinitionID AND tblProperty.fkLanguageBranchID<>tblPage.fkMasterLanguageBranchID
		END
		DELETE tblWorkProperty
		FROM tblWorkProperty
		INNER JOIN tblWorkPage ON tblWorkProperty.fkWorkPageID=tblWorkPage.pkID
		INNER JOIN tblPage ON tblPage.pkID=tblWorkPage.fkPageID
		WHERE fkPageDefinitionID=@PageDefinitionID AND tblWorkPage.fkLanguageBranchID<>tblPage.fkMasterLanguageBranchID

		DELETE
			tblCategoryPage
		FROM
			tblCategoryPage
		INNER JOIN
			tblPage
		ON
			tblPage.pkID = tblCategoryPage.fkPageID
		WHERE
			CategoryType = @PageDefinitionID
		AND
			tblCategoryPage.fkLanguageBranchID <> tblPage.fkMasterLanguageBranchID

		DELETE
			tblWorkCategory
		FROM
			tblWorkCategory
		INNER JOIN
			tblWorkPage
		ON
			tblWorkCategory.fkWorkPageID = tblWorkPage.pkID
		INNER JOIN
			tblPage
		ON
			tblPage.pkID = tblWorkPage.fkPageID
		WHERE
			CategoryType = @PageDefinitionID
		AND
			tblWorkPage.fkLanguageBranchID <> tblPage.fkMasterLanguageBranchID
	END
END
GO

GO
PRINT N'Dropping [dbo].[netActivityLogAssociatedAndRelatedList]...';

GO
DROP PROCEDURE [dbo].[netActivityLogAssociatedAndRelatedList];

GO
PRINT N'Dropping [dbo].[netActivityLogAssociatedOrRelatedList]...';

GO
DROP PROCEDURE [dbo].[netActivityLogAssociatedOrRelatedList];

GO
PRINT N'Creating [dbo].[tblActivityLogAssociation].[IDX_tblActivityLogAssociation_To]...';

GO
CREATE NONCLUSTERED INDEX [IDX_tblActivityLogAssociation_To]
    ON [dbo].[tblActivityLogAssociation]([To] ASC);

GO
PRINT N'Altering [dbo].[netActivityLogAssociationDeleteRelated]...';

GO
ALTER PROCEDURE [dbo].[netActivityLogAssociationDeleteRelated]
(
	@AssociatedItem	[nvarchar](255),
	@RelatedItem	[nvarchar](255)
)

AS
BEGIN
	DECLARE @RelatedItemLike NVARCHAR(256)
	SET @RelatedItemLike = @RelatedItem + '%'
	DELETE FROM [tblActivityLogAssociation]
	FROM [tblActivityLogAssociation] AS TCLA INNER JOIN [tblActivityLog] AS TCL ON TCLA.[To] = TCL.pkID
	WHERE (TCLA.[From] = @AssociatedItem AND TCL.[RelatedItem] LIKE @RelatedItemLike)
	OR (TCLA.[From] LIKE @RelatedItemLike AND TCL.[RelatedItem] LIKE @AssociatedItem)
END
GO
PRINT N'Altering [dbo].[netActivityLogEntrySave]...';

GO
ALTER PROCEDURE [dbo].[netActivityLogEntrySave]
  (@LogData          [nvarchar](max) = NULL,
   @Type			 [nvarchar](255),
   @Action			 INTEGER = 0,
   @ChangedBy        [nvarchar](255),
   @RelatedItem		 [nvarchar](255),
   @Deleted			 [BIT] =  0,
   @Id				 BIGINT = 0 OUTPUT,
   @ChangeDate       DATETIME,
   @Associations	 dbo.StringParameterTable READONLY
)

AS
BEGIN
	IF (@Id = 0)
	BEGIN
       INSERT INTO [tblActivityLog] VALUES(@LogData,
                                       @ChangeDate,
                                       @Type,
                                       @Action,
                                       @ChangedBy,
									   @RelatedItem,
									   @Deleted)
		SET @Id = SCOPE_IDENTITY()
	END
	ELSE
	BEGIN
		UPDATE [tblActivityLog] SET
			[LogData] = @LogData,
			[ChangeDate] = @ChangeDate,
			[Type] = @Type,
			[Action] = @Action,
			[ChangedBy] = @ChangedBy,
			[RelatedItem] = @RelatedItem,
			[Deleted] = @Deleted
		WHERE pkID = @Id
	END

	BEGIN
		MERGE tblActivityLogAssociation AS TARGET
		USING @Associations AS Source
		ON (Target.[To] = @Id AND Target.[From] = Source.String)
		WHEN NOT MATCHED BY Target THEN
			INSERT ([To], [From])
			VALUES (@Id, Source.String);
	END
END
GO

PRINT N'Creating [dbo].[netActivityLogAssociatedAllList]...';

GO
CREATE PROCEDURE [dbo].[netActivityLogAssociatedAllList]
(
	@Associations	dbo.StringParameterTable READONLY,
	@StartIndex			BIGINT = NULL,
	@MaxCount			INT = NULL
)

AS
BEGIN

	DECLARE @MatchAllCount INT
	SET @MatchAllCount = (SELECT COUNT(*) FROM @Associations);

	--Get all entries that match any uri
	WITH MatchedUrisCTE
	AS
	(
		SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
				FROM [tblActivityLog]
				INNER JOIN tblActivityLogAssociation ON pkID = [To]
				WHERE (EXISTS(SELECT * FROM @Associations WHERE [From] LIKE String + '%'))
		UNION ALL
		SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
				FROM [tblActivityLog]
				WHERE
				(EXISTS(SELECT * FROM @Associations WHERE RelatedItem LIKE String + '%'))
	),
	--Filter out to get only entries that match all of the uris
	GroupedMatchedUrisCTE
	AS
	(
		SELECT DISTINCT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
				FROM MatchedUrisCTE
				GROUP BY pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
				HAVING COUNT(pkID) = @MatchAllCount
	),

	-- Paged result
	PagedResultCTE AS
	(
		SELECT TOP(@MaxCount) TCL.pkID, TCL.Action, TCL.Type, TCL.ChangeDate, TCL.ChangedBy, TCL.LogData,
			TCL.RelatedItem, TCL.Deleted,
			(SELECT COUNT(*) FROM GroupedMatchedUrisCTE) AS 'TotalCount'
		FROM GroupedMatchedUrisCTE as TCL
		WHERE TCL.pkID <= @StartIndex
		ORDER BY TCL.pkID DESC
	)

	SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted, TotalCount FROM PagedResultCTE
END
GO
PRINT N'Creating [dbo].[netActivityLogAssociatedAnyList]...';

GO
CREATE PROCEDURE [dbo].[netActivityLogAssociatedAnyList]
(
	@Associations	 dbo.StringParameterTable READONLY,
	@StartIndex			BIGINT = NULL,
	@MaxCount			INT = NULL
)

AS
BEGIN

	WITH MatchedAssociatedOrRelatedIdsCTE
	AS
	(
		SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted,
		ROW_NUMBER() OVER (ORDER BY pkID) AS TotalCount
		FROM
		(SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
			FROM [tblActivityLog]
			LEFT OUTER JOIN [tblActivityLogAssociation] TAR ON pkID = TAR.[To]
			WHERE
				(EXISTS(SELECT * FROM @Associations WHERE RelatedItem LIKE String + '%')
				AND
				Deleted = 0)
				OR
				(EXISTS(SELECT * FROM @Associations WHERE TAR.[From] LIKE String + '%')
				AND
				Deleted = 0))
		AS Result
	),
	PagedResultCTE AS
	(
		SELECT TOP(@MaxCount) TCL.pkID, TCL.Action, TCL.Type, TCL.ChangeDate, TCL.ChangedBy, TCL.LogData,
			TCL.RelatedItem, TCL.Deleted,
			(SELECT COUNT(*) FROM MatchedAssociatedOrRelatedIdsCTE) AS 'TotalCount'
		FROM MatchedAssociatedOrRelatedIdsCTE  as TCL
		WHERE TCL.pkID <= @StartIndex
		ORDER BY TCL.pkID DESC
	)

	SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted, TotalCount FROM PagedResultCTE

END
GO
PRINT N'Creating [dbo].[netActivityLogAssociatedList]...';

GO
CREATE PROCEDURE [dbo].[netActivityLogAssociatedList]
(
	@MatchAll			dbo.StringParameterTable READONLY,
	@MatchAny			dbo.StringParameterTable READONLY,
	@StartIndex			BIGINT = NULL,
	@MaxCount			INT = NULL
)

AS
BEGIN
	DECLARE @MatchAllCount INT
	SET @MatchAllCount = (SELECT COUNT(*) FROM @MatchAll);

	--Get all entries that match any uri
	WITH MatchedUrisCTE
	AS
	(
		SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
				FROM [tblActivityLog]
				INNER JOIN tblActivityLogAssociation ON pkID = [To]
				WHERE (EXISTS(SELECT * FROM @MatchAll WHERE [From] LIKE String + '%'))
		UNION ALL
		SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
				FROM [tblActivityLog]
				WHERE
				(EXISTS(SELECT * FROM @MatchAll WHERE RelatedItem LIKE String + '%'))
	),
	--Filter out to get only entries that match all of the uris
	GroupedMatchedUrisCTE
	AS
	(
		SELECT DISTINCT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
				FROM MatchedUrisCTE
				GROUP BY pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
				HAVING COUNT(pkID) = @MatchAllCount
	),

	-- Then Match Any
	MatchedAssociatedOrRelatedIdsCTE
	AS
	(
		SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted,
		ROW_NUMBER() OVER (ORDER BY pkID) AS TotalCount
		FROM
		(SELECT T.pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted
			FROM GroupedMatchedUrisCTE as T
			LEFT OUTER JOIN [tblActivityLogAssociation] TAR ON pkID = TAR.[To]
			WHERE
				(EXISTS(SELECT * FROM @MatchAny WHERE RelatedItem LIKE String + '%') AND Deleted = 0)
				OR
				(EXISTS(SELECT * FROM @MatchAny WHERE TAR.[From] LIKE String + '%') AND Deleted = 0))
		AS Result
	),

	--get paged result
	PagedResultCTE AS
	(
		SELECT TOP(@MaxCount) TCL.pkID, TCL.Action, TCL.Type, TCL.ChangeDate, TCL.ChangedBy, TCL.LogData,
			TCL.RelatedItem, TCL.Deleted,
			(SELECT COUNT(*) FROM MatchedAssociatedOrRelatedIdsCTE) AS 'TotalCount'
		FROM MatchedAssociatedOrRelatedIdsCTE  as TCL
		WHERE TCL.pkID <= @StartIndex
		ORDER BY TCL.pkID DESC
	)

	SELECT pkID, Action, Type, ChangeDate, ChangedBy, LogData, RelatedItem, Deleted, TotalCount FROM PagedResultCTE
END
GO

PRINT N'Altering [dbo].[sp_DatabaseVersion]...';

GO
ALTER PROCEDURE [dbo].[sp_DatabaseVersion]
AS
	RETURN 7023
GO

PRINT N'Update complete.';

GO


text:
package org.opencb.opencga.catalog.utils;

import org.opencb.opencga.catalog.models.File;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author Jacobo Coll <jacobo167@gmail.com>
 */
public class FormatDetector {

    private static final Map<File.Format, Pattern> FORMAT_MAP = new HashMap<>();

    static {
        FORMAT_MAP.put(File.Format.IMAGE, Pattern.compile(".*\\.(png|jpg|bmp|svg|gif|jpeg|tfg)(\\.[\\w]+)*", Pattern.CASE_INSENSITIVE));
    }

    /**
     *
     * @param uri       Existing file uri to the file
     * @return File.Format. UNKNOWN if can't detect any format.
     */
    public static File.Format detect(URI uri) {
        for (Map.Entry<File.Format, Pattern> entry : FORMAT_MAP.entrySet()) {
            if (entry.getValue().matcher(uri.getPath()).matches()) {
                return entry.getKey();
            }
        }

        String path = uri.getPath();
        String extension = com.google.common.io.Files.getFileExtension(path);
        if (CompressionDetector.getCompression(extension) != File.Compression.NONE) {
            path = com.google.common.io.Files.getNameWithoutExtension(path);
            extension = com.google.common.io.Files.getFileExtension(path);
        }

        switch (extension.toLowerCase()) {
            case "vcf":
                return File.Format.VCF;
            case "bcf":
                return File.Format.BCF;
            case "bam":
                return File.Format.BAM;
            case "bai":
                return File.Format.BAI;
            case "sam":
                return File.Format.SAM;
            case "cram":
                return File.Format.CRAM;
            case "ped":
                return File.Format.PED;
            case "fastq":
                return File.Format.FASTQ;
            case "tsv":
                return File.Format.TAB_SEPARATED_VALUES;
            case "csv":
                return File.Format.COMMA_SEPARATED_VALUES;
            case "txt":
            case "log":
                return File.Format.PLAIN;
            case "xml":
                return File.Format.XML;
            case "json":
                return File.Format.JSON;
            case "proto":
                return File.Format.PROTOCOL_BUFFER;
            case "avro":
                return File.Format.AVRO;
            case "parquet":
                return File.Format.PARQUET;
            case "png":
            case "bmp":
            case "svg":
            case "gif":
            case "jpeg":
            case "tif":
                return File.Format.IMAGE;
            default:
                break;
        }

        //PLAIN
        return File.Format.UNKNOWN;
    }

}

redpajama_set_name: RedPajamaGithub


text:
/**
 *
 */
package org.openforis.collect.designer.composer;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import org.apache.commons.lang3.StringUtils;
import org.openforis.collect.model.ui.UITab;
import org.openforis.collect.model.ui.UITabsGroup;
import org.zkoss.bind.BindComposer;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.DependsOn;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Component;

/**
 * @author S. Ricci
 *
 */
public class TabsGroupComposer extends BindComposer<Component> {

	private static final long serialVersionUID = 1L;

	public static UITab FAKE_ADD_TAB;

	static {
		FAKE_ADD_TAB = new UITab();
		FAKE_ADD_TAB.setLabel("+");
	}

	private UITabsGroup tabsGroup;

	@Init
	public void init(@ExecutionArgParam("tabsGroup") UITabsGroup tabsGroup) {
		this.tabsGroup = tabsGroup;
	}

	@Command
	@NotifyChange({"tabs"})
	public void addTab() {
		UITab tab = new UITab();
		String tabName = generateNewTabName(tabsGroup);
		tab.setName(tabName);
		tabsGroup.addTab(tab);
	}

	@Command
	@NotifyChange({"tabs"})
	public void removeTab(@BindingParam("tab") UITab tab) {
		UITabsGroup parent = tab.getParent();
		parent.removeTab(tab);
	}

	private String generateNewTabName(UITabsGroup parentGroup) {
		String prefix = "tab_";
		Stack<Integer> parts = new Stack<Integer>();
		UITabsGroup currentGroup = parentGroup;
		do {
			int position = currentGroup.getTabs().size() + 1;
			parts.push(position);
			currentGroup = currentGroup.getParent();
		} while ( currentGroup != null );
		String suffix = StringUtils.join(parts.toArray(), "_");
		String tabName = prefix + suffix;
		return tabName;
	}

//	@GlobalCommand
//	public void tabDefinitionChanged(@BindingParam("tabDefinition") UITabDefinition tabDefinition) {
//		group = tabDefinition;
//	}

	public UITabsGroup getTabsGroup() {
		return tabsGroup;
	}

	public List<UITab> getTabs() {
		return tabsGroup != null ? tabsGroup.getTabs(): null;
	}

	@DependsOn("tabs")
	public List<UITab> getTabsPlusAddButton() {
		List<UITab> tabs = new ArrayList<UITab>();
		if ( tabsGroup != null ) {
			tabs.addAll(tabsGroup.getTabs());
		}
		tabs.add(FAKE_ADD_TAB);
		return tabs;
	}

	public UITab getFakeAddTab() {
		return FAKE_ADD_TAB;
	}

}


text:
#pragma once

//////////////////////////////////////////////////////////////////////////////////////////////////
//
// file: ContentInspector.h
//
//	Author Sergey Solokhin (Neill3d)
//
//	GitHub page - https://github.com/Neill3d/MoPlugs
//	Licensed under BSD 3-Clause - https://github.com/Neill3d/MoPlugs/blob/master/LICENSE
//
///////////////////////////////////////////////////////////////////////////////////////////////////

//--- SDK include
#include <fbsdk/fbsdk.h>

#include <vector>
#include <map>

#include <stack>
#include <algorithm>

#include "graphics\UniformBuffer.h"
#include "graphics\OGL_Utils.h"
#include "shared_glsl.h"

#include "..\Common\Common_shader.h"

#include "callback_factory.h"
#include "callbacks.h"

#include "render_conveyer.h"
#include "render_layer_info.h"

// TODO: compute 10 remove items and start full update !!

// check which item we should update next frame, check for animated properties

#define RESOURCE_SINGLE_UPDATE	2
#define RESOURCE_ANIMATED		4
#define RESOURCE_DELETED		8
#define RESOURCE_SYSTEM			16
#define RESOURCE_SUBDATA_UPDATE	32		// update meshes data (attach/detach material, shader) inside a model

// for inspector classification
#define RESOURCE_NONE			0
#define	RESOURCE_TEXTURE		1
#define RESOURCE_SHADER			2
#define RESOURCE_MATERIAL		3

//
void ConstructFromFBShader( FBShader *pShader, ShaderGLSL &shader );
//void ConstructFromFBMaterial( FBMaterial *pMaterial, MaterialGLSL &mat );

////////////////////////////////////////////////////////////////////////////////////////
//

template <typename MBT, typename GLT>
class CResourceInspector
{
protected:

	virtual void DefaultGLSLResource( GLT &item )
	{}
	virtual void ConvertResource( MBT *mbitem, FBEvaluateInfo *pEvalInfo, GLT &item, bool subdata )
	{}

	virtual bool IsAnimated( MBT *mbitem ) {
		return false;
	}

	virtual bool FilterComponentHard( MBT *mbitem ) {
		return true;
	}

	/// this filtering could be added to the pending stack to be processed one more time during rendering preparation

	virtual bool FilterComponentLight( MBT *mbitem ) {
		return true;
	}

	// Hard update
	virtual void UpdateAll(FBEvaluateInfo *pEvalInfo)
	{}

	virtual bool ProcessNeedFullUpdate()
	{
		return false;
	}

	virtual void OnProcessFinished(bool updated)
	{}

public:

	// a constructor
	CResourceInspector()
	{
		mNeedFullUpdate = false;
	}

	// a destructor
	virtual ~CResourceInspector()
	{}

	virtual int	GetResourceType() const {
		return RESOURCE_NONE;
	}

	// callbacks for other classes to sync resources
	virtual void OnItemAdd( MBT *mbitem )
	{}

	virtual void OnItemDelete( MBT *mbitem)
	{}

	void CheckAnimatedFlag( MBT *mbitem )
	{
		auto iter = mResourceMap.find(mbitem);

		if (iter != end(mResourceMap) )
		{
			int &updateFlag = mUpdateVector[iter->second];

			if (IsAnimated(mbitem) )
			{
				if ( (updateFlag & RESOURCE_ANIMATED) == 0)
					updateFlag |= RESOURCE_ANIMATED;
			}
			else
			{
				if (updateFlag & RESOURCE_ANIMATED)
					updateFlag &= ~RESOURCE_ANIMATED;
			}
		}
	}

	void NeedUpdateByIndex( int itemIndex, bool animated, bool subdata )
	{
		int &updateFlag = mUpdateVector[itemIndex];

		if (animated)
			updateFlag = RESOURCE_SINGLE_UPDATE | RESOURCE_ANIMATED;
		else if ( (updateFlag & RESOURCE_SINGLE_UPDATE) == 0)
			updateFlag |= RESOURCE_SINGLE_UPDATE;

		if (subdata && (updateFlag & RESOURCE_SUBDATA_UPDATE) == 0)
			updateFlag |= RESOURCE_SUBDATA_UPDATE;
	}

	virtual void NeedUpdate( MBT *mbitem, bool animated, bool subdata )
	{
		if (false == FilterComponentHard(mbitem) )
			return;

		if (true == mNeedFullUpdate)
			return;

		auto iter = mResourceMap.find(mbitem);

		if (iter != end(mResourceMap) )
		{
			NeedUpdateByIndex(iter->second, animated, subdata);
		}
		else
		{
			// !!
			FBString name(mbitem->Name);
			printf ("how to deal with a missing resource - %s?!\n", name);

			bool isPending = false;

			auto iter = std::find( begin(mPendingResource), end(mPendingResource), mbitem );
			if (iter != end(mPendingResource) )
			{
				isPending = true;
				printf ("  > the resource is pending\n" );
			}

			// let's try to add if not exist !
			if (isPending == false)
			{
				Add(mbitem);
			}
		}
	}

	void NeedFullUpdate()
	{
		mNeedFullUpdate = true;
	}
	const bool IsFullUpdateNeeded() const {
		return mNeedFullUpdate;
	}

	void ProcessPendingResource()
	{
		size_t count= 0;
		for (auto iter = begin(mPendingResource); iter!=end(mPendingResource); ++iter)
		{
			if (nullptr == *iter)
				continue;

			if (false == Add( *iter, false ) )
				count += 1;
			else
				*iter = nullptr;
		}

		if (count == 0)
			mPendingResource.clear();
	}

	bool Process(FBEvaluateInfo *pEvalInfo)
	{
		mSubDataUpdated = false;
		bool updated = false;

		if (true == ProcessNeedFullUpdate() )
			mNeedFullUpdate = true;

		if (mNeedFullUpdate)
		{
			mPendingResource.clear();

			UpdateAll(pEvalInfo);
			mNeedFullUpdate = false;
			mSubDataUpdated = true;

			auto iter=begin(mGLSLResource);
			auto resource = begin(mResourceVector);
			auto updateIter=begin(mUpdateVector);

			for (; iter!=end(mGLSLResource); ++iter, ++resource, ++updateIter)
			{
				int updateFlag = *updateIter;
				if (updateFlag & RESOURCE_DELETED
					|| updateFlag & RESOURCE_SYSTEM)
					continue;

				ConvertResource(*resource, pEvalInfo, *iter, false);

				if (updateFlag & RESOURCE_SINGLE_UPDATE)
					updateFlag &= ~RESOURCE_SINGLE_UPDATE;
				*updateIter = updateFlag;
			}
			updated = true;
		}
		else
		{
			ProcessPendingResource();

			auto updateIter=begin(mUpdateVector);
			auto glslIter = begin(mGLSLResource);
			auto resource = begin(mResourceVector);

			for ( ; updateIter!=end(mUpdateVector); ++updateIter, ++glslIter, ++resource)
			{
				int updateFlag = *updateIter;

				if (updateFlag & RESOURCE_DELETED
					|| updateFlag & RESOURCE_SYSTEM)
					continue;

				if (updateFlag & RESOURCE_SUBDATA_UPDATE)
				{
					mSubDataUpdated = true;
					updateFlag &= ~RESOURCE_SUBDATA_UPDATE;
					ConvertResource(*resource, pEvalInfo, *glslIter, true);
					// TODO: check if that is correct ?!
					*updateIter = updateFlag;
				}

				if (updateFlag & RESOURCE_SINGLE_UPDATE)
				{
					ConvertResource(*resource, pEvalInfo, *glslIter, false);
					updateFlag &= ~RESOURCE_SINGLE_UPDATE;
					*updateIter = updateFlag;
					updated = true;
				}
				else if (updateFlag & RESOURCE_ANIMATED)
				{
					ConvertResource(*resource, pEvalInfo, *glslIter, false);
					updated = true;
				}
			}
		}

		OnProcessFinished(updated);
		return updated;
	}

	bool IsSubDataUpdated() const {
		return mSubDataUpdated;
	}

	int FindResourceIndex( MBT *mbitem )
	{
		auto iter = mResourceMap.find(mbitem);

		if (iter != end(mResourceMap) )
		{
			return iter->second;
		}

		return -1;
	}

	void Clear()
	{
		mResourceMap.clear();
		mResourceVector.clear();
		mGLSLResource.clear();
		mUpdateVector.clear();
	}

	virtual bool Add( MBT *mbitem, bool addToPendingStack=true )
	{
		if (false == FilterComponentHard(mbitem) )
		{
			return false;
		}

		if (false == FilterComponentLight(mbitem) )
		{
			if (addToPendingStack)
				mPendingResource.push_back(mbitem);

			return false;
		}

		size_t index = mGLSLResource.size();

		mResourceMap[mbitem] = (int) index;

		GLT newItem;
		DefaultGLSLResource( newItem );
		mGLSLResource.push_back(newItem);

		int updateFlag = RESOURCE_SINGLE_UPDATE;
		if (IsAnimated(mbitem) )
			updateFlag |= RESOURCE_ANIMATED;

		mUpdateVector.push_back(updateFlag);
		mResourceVector.push_back(mbitem);

		OnItemAdd( mbitem );

		return true;
	}

	virtual void Delete( MBT *mbitem )
	{
		auto iter = mResourceMap.find(mbitem);

		if (iter != end(mResourceMap) )
		{
			int &updateFlag = mUpdateVector[iter->second];
			if ( (updateFlag & RESOURCE_SYSTEM) == 0)
			{
				updateFlag = RESOURCE_DELETED;

				OnItemDelete(mbitem);
			}

			// TODO: if we already put a RESOURCE_DELETED flag, why do we need to erase element here ??!!
			mResourceMap.erase(iter);
		}

		auto pendingIter = std::find(begin(mPendingResource), end(mPendingResource), mbitem);
		if (pendingIter != end(mPendingResource) )
		{
			mPendingResource.erase(pendingIter);
		}
	}

	/*
	// global resize
	void ReSize(const size_t size)
	{

		mGLSLResource.resize(size);

		mNeedFullUpdate = true;
	}
	*/

	size_t GetNumberOfItems() const {
		return mGLSLResource.size();
	}
	const GLT *GetData() const {
		return mGLSLResource.data();
	}

	const std::vector<MBT*> &GetResourceVector() const {
		return mResourceVector;
	}

	const std::vector<int> &GetUpdateVector() const {
		return mUpdateVector;
	}

	bool IsDeleted(const int index) {
		return (mUpdateVector[index] & RESOURCE_DELETED);
	}

	/*
	int GetNumberOfConnections(int itemIndex, int resourceType) const
	{
		int count = 0;

		if (index >= 0 && index < mConnectionVector.size() )
		{
			ElementConnection &conn = mConnectionVector[itemIndex];

			for (int i=0; i<conn.numberOfconnections; ++i)
			{
				if (conn.connections[i].type == resourceType)
					count += 1;
			}
		}

		return count;
	}

	int GetConnectionAnotherIndex(int itemIndex, int resourceType, int connectionIndex)
	{
		int count = 0;
		if (index >= 0 && index < mConnectionVector.size() )
		{
			ElementConnection &conn = mConnectionVector[itemIndex];

			for (int i=0; i<conn.numberOfconnections; ++i)
			{
				if (conn.connections[i].type == resourceType)
				{
					if (count == connectionIndex)
						return conn.connections[i].index;

					count += 1;
				}
			}
		}

		return -1;
	}

	FBComponent *GetConnectionAnotherComponent(int itemIndex, int resourceType, int connectionIndex)
	{
		int count = 0;
		if (index >= 0 && index < mConnectionVector.size() )
		{
			ElementConnection &conn = mConnectionVector[itemIndex];

			for (int i=0; i<conn.numberOfconnections; ++i)
			{
				if (conn.connections[i].type == resourceType)
				{
					if (count == connectionIndex)
						return conn.connections[i].pcomp;

					count += 1;
				}
			}
		}

		return nullptr;
	}

	// connect this element with the element from another inspector
	bool Connect(int itemIndex, int resourceType, int anotherIndex, FBComponent *anotherElement)
	{
		ElementConnection &conn = mConnectionVector[itemIndex];

		for (int i=0; i<conn.numberOfConnections; ++i)
		{
			// ALREADY CONNECTED !
			if ( conn.connections[i].type == resourceType && conn.connections[i].pcomp == anotherElement )
				return true;
		}

		for (int i=0; i<conn.numberOfConnections; ++i)
		{
			if ( conn.connections[i].type == RESOURCE_NONE )
			{
				conn.connections[i].type = resourceType;
				conn.connections[i].pcomp = anotherElement;
				conn.connections[i].index = anotherIndex;

				return true;
			}
		}

		return false;
	}

	bool Connect(MBT *mbt, CResourceInspector *anotherInspector, FBComponent *anotherElement)
	{
		auto iter = mResourceMap[mbt];
		if (iter != end(mResourceMap) )
		{
			ElementConnection &conn = mConnectionVector[iter->second];

			for (int i=0; i<conn.numberOfConnections; ++i)
			{
				if ( conn.connections[i].type == RESOURCE_NONE )
				{
					conn.connections[i].type = anotherInspector->GetResourceType();
					conn.connections[i].pcomp = anotherElement;

					int anotherIndex = anotherInspector->FindResourceIndex(anotherElement);
					conn.connections[i].index = anotherIndex;

					return true;
				}

			}
		}
		else
		{
			printf ("element is not found!\n");
		}
		return false;
	}

	// disconnect mbt with the specified component
	bool Disconnect(MBT *mbt, FBComponent *anotherElement)
	{
		auto iter = mResourceMap[mbt];
		if (iter != end(mResourceMap) )
		{
			ElementConnection &conn = mConnectionVector[iter->second];

			for (int i=0; i<conn.numberOfConnections; ++i)
			{
				if ( conn.connections[i].type != RESOURCE_NONE
					&& conn.connections[i].pcomp == anotherElement )
				{
					conn.connections[i].type = RESOURCE_NONE;
					return true;
				}
			}
		}
		else
		{
			printf ("element is not found!\n");
		}

		return false;
	}
	*/
protected:

	bool				mNeedFullUpdate;

	bool				mSubDataUpdated;

	// convert from class pointer to glsl resources index
	std::map<MBT*, int>			mResourceMap;
	std::vector<MBT*>			mResourceVector;

	// flags for update
	std::vector<int>			mUpdateVector;

	// prepared converted GLSL struct vector to load into gpu
	std::vector<GLT>			mGLSLResource;

	// try to add components during render preparation
	std::deque<MBT*>			mPendingResource;

	// connectors for this element - for example material with texture
	//  model <-> mesh, mesh <-> material, model <-> shader
	/*
	struct ElementConnection
	{
		struct Connection
		{
			int				type;	// type of element, determine inspector
			int				index;	// index to element in another inspector
			FBComponent		*pcomp;
		};

		int					numberOfConnections;
		Connection			connections[2];

		void Empty(int index)
		{
			Connection &conn = connectons[index];
			conn.type = RESOURCE_NONE;
			conn.index = -1;
			conn.pcomp = nullptr;
		}
	};

	void EmptyConnection(ElementConnection &con)
	{
		conn.numberOfConnections = 0;
		connections.Empty(0);
		connections.Empty(1);
	}

	std::vector<ElementConnection>			mConnectionVector;
	*/
};

///////////////////////////////////////////////////
//

class CTexturesInspector : public CResourceInspector<FBTexture, TextureGLSL>
{
protected:

	virtual void DefaultGLSLResource( TextureGLSL &item )
	{
		item.address = 0;
		item.width = 1;
		item.height = 1;
		item.transform.identity();
		//item.format.w = 1.0f;
	}
	virtual void ConvertResource( FBTexture *mbitem, FBEvaluateInfo *pEvalInfo, TextureGLSL &item, bool subdata ) override
	{
		item.address = 0;
		item.width = mbitem->Width;
		item.height = mbitem->Height;

		double *matrix = mbitem->GetMatrix();
		for (int i=0; i<16; ++i)
		{
			item.transform.mat_array[i] = (float) matrix[i];
		}

		// try to get information about video format
		/*
		item.format.w = 1.0f;

		FBVideo *pVideo = mbitem->Video;
		if ( nullptr != pVideo && FBIS(pVideo, FBVideoClip) )
		{
			FBVideoClip *pClip = (FBVideoClip*) pVideo;

			FBVideoFormat format = pClip->Format;
			if (kFBVideoFormat_RGB_24 == format || kFBVideoFormat_BGR_16 == format
				|| kFBVideoFormat_BGR_24 == format )
			{
				item.format.w = 0.0f;
			}
		}
		*/
	}

	virtual bool IsAnimated( FBTexture *mbitem )
	{
		if (mbitem->Translation.IsAnimated()
			|| mbitem->Rotation.IsAnimated()
			|| mbitem->Scaling.IsAnimated() )
		{
			return true;
		}

		return false;
	}

public:

	virtual int	GetResourceType() const {
		return RESOURCE_TEXTURE;
	}

	virtual void UpdateAll(FBEvaluateInfo *pEvalInfo) override
	{
		FBScene *pScene = FBSystem::TheOne().Scene;

		int count = pScene->Textures.GetCount();

		mResourceVector.resize(count);
		mUpdateVector.resize(count);
		mGLSLResource.resize(count);
		mResourceMap.clear();

		for (int i=0; i<count; ++i)
		{
			FBTexture *pTexture = pScene->Textures[i];
			mResourceMap[pTexture] = i;
			mResourceVector[i] = pTexture;

			ConvertResource(pTexture, pEvalInfo, mGLSLResource[i], false);

			mUpdateVector[i] = 0;
			if ( IsAnimated(pTexture) )
				mUpdateVector[i] |= RESOURCE_ANIMATED;
		}
	}

	void MoBuInitTextures(FBRenderOptions *pRenderOptions) {

		/*
		auto flagIter = begin(mUpdateVector);

		for (auto iter=begin(mResourceVector);
				iter!=end(mResourceVector); ++iter, ++flagIter)
		{

			if (*flagIter & RESOURCE_DELETED > 0)
				continue;

			FBTexture *pTexture = *iter;
			pTexture->OGLInit(pRenderOptions);
		}
		*/

		FBScene *pScene = FBSystem::TheOne().Scene;

		for (int i=0, count=pScene->Textures.GetCount(); i<count; ++i)
		{
			FBTexture *pTexture = pScene->Textures[i];
			glActiveTexture(GL_TEXTURE0);
			pTexture->OGLInit(pRenderOptions);
		}

	}
};

////////////////////////////////////////////////////////////////////////////////////
//
class CShadersInspector : public CResourceInspector<FBShader, ShaderGLSL>
{
public:

	// this wrap helps to avoid <mat>.find searching info for each shader per pass !
	struct MyFBShaderWrap
	{
		FBShader			*pShader;
		CBaseShaderInfo		*pShaderInfo;
	};

	struct MyFBShaderInfoWrap
	{
		CBaseShaderInfo		*pShaderInfo;
		CBaseShaderCallback	*pCallback;
	};

	const std::vector<CBaseShaderCallback*> &GetShaderTypesVector() const
	{
		return mShadersFactory.GetShaderTypesVector();
	}
	/*
	std::multimap<CBaseShaderCallback*, MyFBShaderWrap> &GetShaderIntancesMultimap() // (int pass)
	{
		return mShaderInstances; // [pass];
	}
	*/
	/*
	CBaseShaderInfo *AllocateANewShaderInfo( FBShader *pShader, CBaseShaderCallback *pCallback )
	{
		CBaseShaderInfo *pShaderInfo = pCallback->CreateANewShaderInfo(pShader);
		MyFBShaderInfoWrap wrap = { pShaderInfo, pCallback };

		mShaderInfos.insert( std::make_pair( pShader, wrap ) );

		return pShaderInfo;
	}
	*/
	CBaseShaderInfo *GetShaderInfo(FBShader *pShader,
		bool createIfEmtpy, CBaseShaderCallback *pCallback);

	// process pending items, process shader info, full sort if needed

	void EventBeforeRenderNotify();
	void EventConnNotify(HISender pSender, HKEvent pEvent);

	void UpdateGPUBuffer( CGPUBuffer *pBuffer );

	// check if shader has changes important data when we have to re-sort the shader instances
	void EventDataNotify(HISender pSender, HKEvent pEvent);

	void AskToUpdateAllShadersData();
	void ChangeContext();

	CBaseShaderInfo *GetShaderCallbackInfo(const size_t ncallback, const size_t nshader) const
	{
		return mShaderCallbackInfos[ncallback][nshader];
	}

	std::vector<FBShader*>	&GetShaderGroupShaders(const int groupId) {
		return mSortedShaders[groupId];
	}

	const CRenderLayerArray &GetRenderLayersInfo() const {
		return mRenderLayers;
	}

protected:

	bool						mIsCombinationsUpdated;

	std::vector<ShaderGLSL>		mCombinationsVector;

protected:

	// pre-sorted list of shaders

	// how to determine shader type ?
	//  store index and type or put into a lot of arrays

	// multimap where key - callback type (index in the factory)
	//				values - shader instances in the ResourceVector

	//std::multimap<CBaseShaderCallback*, MyFBShaderWrap>		mShaderInstances; //[SHADER_PASS_COUNT];

	// number of shader in each callback
	//int														mShaderCounts; //[SHADER_PASS_COUNT];

	// store additional callback information depends on a shader type
	//  what if shader has several callbacks and each shader-callback combination whant's own shaderInfo
	//std::multimap<FBShader*, MyFBShaderInfoWrap>			mShaderInfos;

	// for each shader, for each call - Callback - FBShader information
	std::vector< std::vector<CBaseShaderInfo*> > mShaderCallbackInfos;

	// for each callback - store vector of shaders
	std::vector< std::vector<FBShader*> >	mSortedShaders;

	void SyncShaderCallbackInfos();

	// sort shaders by shader group id
	void SortShaders();

	CShadersFactory											mShadersFactory;

#define	MAX_PENDING_ITEMS		4

	bool	mNeedFullCallbackSort;	// use flag when pending add or del vectors are full

	// shaders that have beed added to a scene
	int mPendingToAddCount;
	FBShader		*mPendingShadersToAdd[MAX_PENDING_ITEMS];

	// shaders that have been removed from the a scene
	int mPendingToDelCount;
	FBShader		*mPendingShadersToDel[MAX_PENDING_ITEMS];

	// shaders that have been chagned some important properties that cause re-sort !
	int mPendingUpdateCount;
	FBShader		*mPendingShadersToUpdate[MAX_PENDING_ITEMS];

	// TODO: compute for each render layer

	CRenderLayerArray		mRenderLayers;

	void ClearShaderGroupsInfo();
	void SyncShaderGroups();

	void FullSortShaderCallbacks();

	void PendingAdd(FBShader *pShader);
	void PendingDel(FBShader *pShader);
	void PendingUpdate(FBShader *pShader);

	void ClearPendingData();

	void RemoveShaderInfos(FBShader *pShader);

	// do something on user events

	void SortOnShaderChange( FBShader *pShader );

	//	add items to a pending update stack
	// callbacks for other classes to sync resources
	virtual void OnItemAdd( FBShader *pShader ) override;
	virtual void OnItemDelete( FBShader *pShader ) override;

public:
	static void ConstructFromFBShader( FBShader *pShader, FBEvaluateInfo *pEvalInfo, ShaderGLSL &shader );

protected:

	virtual void DefaultGLSLResource( ShaderGLSL &item ) override;
	virtual void ConvertResource( FBShader *mbitem, FBEvaluateInfo *pEvalInfo, ShaderGLSL &item, bool subdata ) override;

	virtual bool IsAnimated( FBShader *mbitem ) override;

public:

	//! a constructor
	CShadersInspector();

	virtual int	GetResourceType() const override {
		return RESOURCE_SHADER;
	}

	virtual void UpdateAll(FBEvaluateInfo *pEvalInfo) override;

	const int FindCombination(FBShader **pShaders);
	void UpdateCombinations();
	void RemoveAllCombinations()
	{
		mCombinationsVector.clear();
		mIsCombinationsUpdated = true;
	}

	void ShaderReplace(ShaderGLSL &outshader, const ShaderGLSL &replaceWith);
	void ShaderAppend(ShaderGLSL &outshader, const ShaderGLSL &appendWith);

	const bool IsCombinationUpdated() const {
		return mIsCombinationsUpdated;
	}
	void ResetCombinationUpdateFlag() {
		mIsCombinationsUpdated = false;
	}
};

//////////////////////////////////////////////////
//

// TODO: connection with textures
//  diffuse connection vector - store FBTexture for each texture or index
//	that will help to avoid search inside a map for each update

// then we can use the same thing for the model <-> mesh connection
//		and model <-> shader connection
//			mesh <-> material connection

class CMaterialsInspector : public CResourceInspector<FBMaterial, MaterialGLSL>
{
protected:

	CTexturesInspector			*mTexturesInspector;

protected:

	virtual void DefaultGLSLResource( MaterialGLSL &item )
	{
		DefaultMaterial(item);
	}
	virtual void ConvertResource( FBMaterial *mbitem, FBEvaluateInfo *pEvalInfo, MaterialGLSL &item, bool subdata ) override
	{
		ConstructFromFBMaterial(mbitem, pEvalInfo, mTexturesInspector, item);

		// update from connection ?!
	}

	virtual bool IsAnimated( FBMaterial *mbitem )
	{
		// TODO:

		return false;
	}

public:

	//! a constructor
	CMaterialsInspector(CTexturesInspector *pTexturesInspector=nullptr)
		: mTexturesInspector(pTexturesInspector)
	{}

	//
	void SetTexturesInspector(CTexturesInspector *pTexturesInspector)
	{
		mTexturesInspector = pTexturesInspector;
	}

	static void ConstructFromFBMaterial( FBMaterial *pMaterial, FBEvaluateInfo *pEvalInfo, CTexturesInspector *pTexInspector, MaterialGLSL &mat );
	//void ConstructFromFBMaterial_Full( FBMaterial *pMaterial, FBEvaluateInfo *pEvalInfo, MaterialGLSL &mat );

	virtual int	GetResourceType() const {
		return RESOURCE_MATERIAL;
	}

	void AttachTexture( FBMaterial *pmaterial, FBTexture *ptexture );
	void DetachTexture( FBMaterial *pmaterial, FBTexture *ptexture );

	virtual void UpdateAll(FBEvaluateInfo *pEvalInfo) override;
};

//////////////////////////////////////////////////
//

class CModelsInspector : public CResourceInspector<FBModel, ModelGLSL>
{
protected:

	size_t		mLastNumberOfShaders;

	CTexturesInspector			*mTexturesInspector;
	CMaterialsInspector			*mMaterialsInspector;
	CShadersInspector			*mShadersInspector;

	// mesh data

	// model to beginning of mesh, fast model->mesh access
	std::map<FBModel*, int>			mModelMeshesMap;
	std::vector<int>				mModelMeshesVector;

	// prepared converted GLSL struct vector to load into gpu
	std::vector<MeshGLSL>			mGLSLMesh;

	// render conveyer - sort meshes by callbacks (shader groups)
	struct SortModelWrap
	{
		int			startMeshId;
		FBModel		*pModel;
	};

	bool					mNeedToSortModels;
	CShadersFactory											mShadersFactory;
	std::vector< std::multimap<FBShader*, SortModelWrap> >	mSortedModels;
	std::vector< int >										mSortedCounts;

	void SortModels();

	virtual bool ProcessNeedFullUpdate() override
	{
		if ( mLastNumberOfShaders != mShadersInspector->GetNumberOfItems() )
		{
			mLastNumberOfShaders = mShadersInspector->GetNumberOfItems();
			return true;
		}

		return false;
	}

	virtual void OnProcessFinished(bool updated)
	{
		if (true == mNeedToSortModels)
		{
			SortModels();
			// TODO: future plan !
			//UpdateConveyer();
			mNeedToSortModels = false;
		}
	}

protected:

	std::auto_ptr<CRenderVertexConveyer>	mRenderConveyer;

	void UpdateConveyer();

public:

	const int GetNumberOfModelsInGroup(const int groupId) const
	{
		const int count = mSortedCounts.at(groupId);
		return count;
	}

	const std::multimap<FBShader*, SortModelWrap> &GetSortedModelsMap(const int groupId) const
	{
		return mSortedModels[groupId];
	}

	const CRenderVertexConveyer	*GetRenderConveyerPtr() const
	{
		return mRenderConveyer.get();
	}

	void UpdateDeformations(FBEvaluateInfo *pEvaluateInfo=nullptr);

	void BindVertexConveyer()
	{
		if (mRenderConveyer.get() )
			mRenderConveyer->Bind();
	}
	void UnBindVertexConveyer()
	{
		if (mRenderConveyer.get() )
			mRenderConveyer->UnBind();
	}

protected:

	void DefaultGLSLMesh( MeshGLSL &item )
	{
		item.color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
		item.lightmap = 1;
		item.material = 0;
		item.model = 0;
		item.shader = 0;
	}

	void ConvertGLSLMesh( FBModelVertexData *pData, const int patchIndex, MeshGLSL &item )
	{
		// all data are connectors, so nothing to do in light convert
	}

	virtual void DefaultGLSLResource( ModelGLSL &item ) override
	{
		item.transform.identity();
		item.normalMatrix.identity();
	}
	virtual void ConvertResource( FBModel *pModel, FBEvaluateInfo *pEvalInfo, ModelGLSL &item, bool subdata ) override
	{
		// TODO: we do that in a Normals update function (using a faster SSE instructions)
		/*
		FBMatrix m;
		mbitem->GetMatrix(m, kModelTransformation_Geometry, true, pEvalInfo);

		for (int j=0; j<16; ++j)
		{
			item.transform.mat_array[j] = (float) m[j];
			//modeldata.normalMatrix.mat_array[j] = (float) m[j];
		}

		invert(item.normalMatrix, item.transform);
		transpose(item.normalMatrix);
		*/

		if (subdata)
		{
			int shaderIndex = FindShaderIndex(pModel);
			FBColor colorId = pModel->UniqueColorId;
			int receiveShadows = pModel->ReceiveShadows.AsInt();

			int meshStartIndex = mModelMeshesMap[pModel];
			MeshGLSL *pMeshData = &mGLSLMesh[meshStartIndex];
			FBModelVertexData *pdata = pModel->ModelVertexData;

			for (int patchIndex=0, patchCount=pdata->GetSubPatchCount();
				patchIndex < patchCount;
				++patchIndex, ++pMeshData)
			{

				pMeshData->shader = shaderIndex;
				pMeshData->lightmap = receiveShadows;
				pMeshData->color = vec4( (float)colorId[0], (float)colorId[1], (float)colorId[2], 1.0);

				FBMaterial *pMaterial = pdata->GetSubPatchMaterial(patchIndex);
				if (mMaterialsInspector && pMaterial)
				{
					pMeshData->material = mMaterialsInspector->FindResourceIndex(pMaterial);
					if (pMeshData->material < 0)
						pMeshData->material = 0;
				}
			}
		}

	}

	const int FindShaderIndex(FBModel *pModel);

	void AreNodesAnimated( FBAnimationNode *pRootNode, bool &isAnimated )
	{
		if (pRootNode && pRootNode->KeyCount > 0)
		{
			isAnimated = true;
			return;
		}

		for (int i=0, count=pRootNode->Nodes.GetCount(); i<count; ++i)
			AreNodesAnimated( pRootNode->Nodes[i], isAnimated );
	}

	virtual bool IsAnimated( FBModel *pModel ) override
	{
		bool isAnimated = false;

		if (pModel->IsConstrained )
			return true;

		FBAnimationNode *pRootNode = pModel->AnimationNode;
		if (pRootNode)
		{
			AreNodesAnimated( pRootNode, isAnimated );
		}

		return isAnimated;
	}

	virtual bool FilterComponentHard( FBModel *pModel ) override
	{
		if (FBIS(pModel, FBScene) || FBIS(pModel, FBCamera) || FBIS(pModel, FBLight) || FBIS(pModel, FBModelNull) || FBIS(pModel, FBModelPath3D) || FBIS(pModel, FBModelSkeleton) )
			return false;

		FBGeometry *pGeom = pModel->Geometry;
		//FBModelVertexData *pData = pModel->ModelVertexData;
		if (nullptr == pGeom ) // || nullptr == pData)
			return false;

		return true;
	}

	/// this filtering could be added to the pending stack to be processed one more time during rendering preparation

	virtual bool FilterComponentLight( FBModel *pModel ) override
	{
		FBModelVertexData *pVertexData = pModel->ModelVertexData;
		 if (pVertexData == nullptr)
			 return false;
		 /*
		 if (pVertexData->GetSubRegionCount() == 0)
			 return false;
			 */
		 if (pVertexData->GetSubPatchCount() == 0)
			 return false;
		return true;
	}

protected:

	// used for calculate size for array allocation
	void CalculateModelCount(FBModel *parentModel, int &modelCount, int &meshCount);

	// go through scene models and fillup our arrays with models and meshes information
	void EnumerateModelAndMesh(FBModel *parentModel, int &modelIndex);

public:

	//! a constructor
	CModelsInspector(CTexturesInspector *pTexturesInspector=nullptr, CMaterialsInspector *pMaterialsInspector=nullptr,
				CShadersInspector *pShadersInspector=nullptr)
		: mTexturesInspector(pTexturesInspector)
		, mMaterialsInspector(pMaterialsInspector)
		, mShadersInspector(pShadersInspector)
	{
		mNeedToSortModels = false;
		mLastNumberOfShaders = 0;
	}

	//
	void SetTexturesInspector(CTexturesInspector *pTexturesInspector)
	{
		mTexturesInspector = pTexturesInspector;
	}
	void SetMaterialsInspector(CMaterialsInspector *pMaterialsInspector)
	{
		mMaterialsInspector = pMaterialsInspector;
	}
	void SetShadersInspector(CShadersInspector *pShadersInspector)
	{
		mShadersInspector = pShadersInspector;
	}

	size_t GetNumberOfMeshItems() const {
		return mGLSLMesh.size();
	}
	const MeshGLSL *GetMeshData() const {
		return mGLSLMesh.data();
	}

	int GetModelMeshIndex(const int modelIndex) {

		return mModelMeshesVector[modelIndex];
	}

	int GetModelMeshIndex(FBModel *pModel) {

		auto iter = mModelMeshesMap.find(pModel);

		if (iter != end(mModelMeshesMap)) {

			//return GetModelMeshIndex(iter->second);
			return iter->second;
		}

		return -1;
	}

	bool IsVisible(const int modelIndex) {

		if ( mUpdateVector[modelIndex] & RESOURCE_DELETED )
			return false;

		return mResourceVector[modelIndex]->IsVisible();
	}

	///////////////////////////////////////////////////////////
	// Light update

	// TODO:
	void AttachMaterial(FBModel *pModel, FBMaterial *pMaterial);
	void DetachMaterial(FBModel *pModel, FBMaterial *pMaterial);

	// TODO: direct textures to model is reflection maps, light maps, etc... not supported yet
	void AttachTexture(FBModel *pModel, FBTexture *pTexture);
	void DetachTexture(FBModel *pModel, FBTexture *pTexture);

	// DONE: at the moment we use only first shader, and skip all others (even FX)

	void AttachShader(FBModel *pModel, FBShader *pShader);
	void DetachShader(FBModel *pModel, FBShader *pShader);

	//////////////////////////////////////////////////////////
	// Hard update !
	virtual void UpdateAll(FBEvaluateInfo *pEvalInfo) override;

	void UpdateNormalMatrices( const double *modelview );

	// add to pending stack, try to add model during rendering prep step
	virtual bool Add( FBModel *pModel, bool addToPendingStack=true ) override;
	virtual void Delete( FBModel *mbitem ) override;
	virtual void NeedUpdate( FBModel *pModel, bool animated, bool subdata ) override;
};


text:
package org.pentaho.di.ui.repository.repositoryexplorer.model;

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

import org.pentaho.di.repository.IUser;
import org.pentaho.di.repository.RepositorySecurityManager;
import org.pentaho.di.repository.ObjectRecipient.Type;
import org.pentaho.ui.xul.XulEventSourceAdapter;

public class UISecurity extends XulEventSourceAdapter {

  public static enum Mode { ADD, EDIT, EDIT_MEMBER  };

  private Type selectedDeck;

  protected IUIUser selectedUser;

  private int selectedUserIndex;

  protected List<IUIUser> userList;

  public UISecurity() {
    userList = new ArrayList<IUIUser>();
  }

  public UISecurity(RepositorySecurityManager rsm) throws Exception {
    this();

    if (rsm != null && rsm.getUsers() != null) {
      for (IUser user : rsm.getUsers()) {
        userList.add(UIObjectRegistry.getInstance().constructUIRepositoryUser(user));
      }
      this.firePropertyChange("userList", null, userList); //$NON-NLS-1$
    }
  }

  public Type getSelectedDeck() {
    return selectedDeck;
  }

  public void setSelectedDeck(Type selectedDeck) {
    this.selectedDeck = selectedDeck;
    this.firePropertyChange("selectedDeck", null, selectedDeck); //$NON-NLS-1$
  }

  public int getSelectedUserIndex() {
    return selectedUserIndex;
  }

  public void setSelectedUserIndex(int selectedUserIndex) {
    this.selectedUserIndex = selectedUserIndex;
    this.firePropertyChange("selectedUserIndex", null, selectedUserIndex); //$NON-NLS-1$
  }

  public IUIUser getSelectedUser() {
    return selectedUser;
  }

  public void setSelectedUser(IUIUser selectedUser) {
    this.selectedUser = selectedUser;
    this.firePropertyChange("selectedUser", null, selectedUser); //$NON-NLS-1$
    setSelectedUserIndex(getIndexOfUser(selectedUser));
  }

  public List<IUIUser> getUserList() {
    return userList;
  }

  public void setUserList(List<IUIUser> userList) {
    this.userList.clear();
    this.userList.addAll(userList);
    this.firePropertyChange("userList", null, userList); //$NON-NLS-1$
  }

  public void updateUser(IUIUser userToUpdate) {
    IUIUser user = getUser(userToUpdate.getName());
    user.setDescription(userToUpdate.getDescription());
    this.firePropertyChange("userList", null, userList); //$NON-NLS-1$
    setSelectedUser(user);
  }

  public void addUser(IUIUser userToAdd) {
    userList.add(userToAdd);
    this.firePropertyChange("userList", null, userList); //$NON-NLS-1$
    setSelectedUser(userToAdd);
  }

  public void removeUser(String name) {
    removeUser(getUser(name));
  }

  public void removeUser(IUIUser userToRemove) {
    int index = getIndexOfUser(userToRemove);
    userList.remove(userToRemove);
    this.firePropertyChange("userList", null, userList); //$NON-NLS-1$
    if (index - 1 >= 0) {
      setSelectedUser(getUserAtIndex(index - 1));
    }
  }

  protected IUIUser getUser(String name) {
    for (IUIUser user : userList) {
      if (user.getName().equals(name)) {
        return user;
      }
    }
    return null;
  }

  private IUIUser getUserAtIndex(int index) {
    return this.userList.get(index);
  }

  private int getIndexOfUser(IUIUser ru) {
    for (int i = 0; i < this.userList.size(); i++) {
      IUIUser user = this.userList.get(i);
      if (ru.getName().equals(user.getName())) {
        return i;
      }
    }
    return -1;
  }
}


text:
class ProfitAndLossController < ApplicationController
  helper :graph
  menu_group "家計簿"
  menu "収支表"

  before_action :check_account

  def show
    year, month = read_target_date
    redirect_to monthly_profit_and_loss_path(:year => year, :month => month)
  end

  def monthly
    write_target_date(params[:year], params[:month])
    @year, @month = read_target_date

    # 費目ごとの合計を得る
    start_inclusive = Date.new(@year.to_i, @month.to_i, 1)
    end_exclusive = start_inclusive >> 1

    # 全口座のフローを得る
    flows = current_user.accounts.flows(start_inclusive, end_exclusive)

    # 前月のデータを得る
    previous_flows = current_user.accounts.flows(start_inclusive << 1, end_exclusive << 1)

    # 表示用のインスタンス変数に格納していく
    @expense_flows = Flow::PlusList.new
    @income_flows = Flow::MinusList.new
    @asset_plus_flows = Flow::PlusList.new
    @asset_minus_flows = Flow::MinusList.new
    for account in flows
      previous = previous_flows.detect{|pa| pa.id == account.id}
      previous_flows.delete(previous)
      case account
        when Account::Expense
          @expense_flows.add_with_previous(account, previous)
        when Account::Income
          @income_flows.add_with_previous(account, previous)
        else
          if account.flow > 0
            @asset_plus_flows.add_with_previous(account, nil)
          elsif account.flow < 0
            @asset_minus_flows.add_with_previous(account, nil)
         end
      end
    end
    # 今月なくて前月あるものを加える
    for previous in previous_flows
      case previous
        when Account::Expense
          @expense_flows.add_with_previous(nil, previous)
        when Account::Income
          @income_flows.add_with_previous(nil, previous)
      end
    end

    # 不明金を得て、収支に加える
    unknowns = current_user.accounts.unknowns(start_inclusive, end_exclusive)
    previous_unknowns = current_user.accounts.unknowns(start_inclusive << 1, end_exclusive << 1)
    for account in unknowns
      previous = previous_unknowns.detect{|pk| pk.id == account.id}
      if account.unknown > 0
        @expense_flows.add_with_previous(account, previous)
      elsif account.unknown < 0
        @income_flows.add_with_previous(account, previous)
      end
    end
    # 今月なくて前月あるものを加える
    for previous in previous_unknowns
      case previous
        when Account::Expense
          @expense_flows.add_with_previous(nil, previous)
        when Account::Income
          @income_flows.add_with_previous(nil, previous)
      end
    end

    @profit = @income_flows.sum - @expense_flows.sum
  end

end


text:
"use strict";
// The MIT License (MIT)
//
// Copyright (c) 2017 Firebase
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
// Providers:
const analytics = require("./providers/analytics");
exports.analytics = analytics;
const auth = require("./providers/auth");
exports.auth = auth;
const apps = require("./apps");
const crashlytics = require("./providers/crashlytics");
exports.crashlytics = crashlytics;
const database = require("./providers/database");
exports.database = database;
const firestore = require("./providers/firestore");
exports.firestore = firestore;
const https = require("./providers/https");
exports.https = https;
const pubsub = require("./providers/pubsub");
exports.pubsub = pubsub;
const remoteConfig = require("./providers/remoteConfig");
exports.remoteConfig = remoteConfig;
const storage = require("./providers/storage");
exports.storage = storage;
const config_1 = require("./config");
const handler_builder_1 = require("./handler-builder");
exports.handler = handler_builder_1.handler;
var app = apps.apps();
exports.app = app;
// // Exported root types:
__export(require("./config"));
__export(require("./cloud-functions"));
__export(require("./function-builder"));
// TEMPORARY WORKAROUND (BUG 63586213):
// Until the Cloud Functions builder can publish FIREBASE_CONFIG, automatically provide it on import based on what
// we can deduce.
if (!process.env.FIREBASE_CONFIG) {
    const cfg = config_1.firebaseConfig();
    if (cfg) {
        process.env.FIREBASE_CONFIG = JSON.stringify(cfg);
    }
    else if (process.env.GCLOUD_PROJECT) {
        console.warn('Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail');
        process.env.FIREBASE_CONFIG = JSON.stringify({
            databaseURL: `${process.env.DATABASE_URL}` ||
                `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`,
            storageBucket: `${process.env.STORAGE_BUCKET_URL}` ||
                `${process.env.GCLOUD_PROJECT}.appspot.com`,
            projectId: process.env.GCLOUD_PROJECT,
        });
    }
    else {
        console.warn('Warning, FIREBASE_CONFIG environment variable is missing. Initializing firebase-admin will fail');
    }
}


text:
package controller

import skinny.controller.feature.BacklogJPLoginFeature
import skinny.oauth2.client.OAuth2User
import skinny.oauth2.client.backlog.BacklogUser

class BacklogJPController extends ApplicationController with BacklogJPLoginFeature {

  override def spaceID     = "seratch"
  override def redirectURI = "http://localhost:8080/example/backlogjp/callback"

  override protected def saveAuthorizedUser(user: BacklogUser): Unit = {
    session.setAttribute("user", user)
  }

  override protected def handleWhenLoginSucceeded(): Any = {
    redirect302(url(Controllers.backlogJp.okUrl))
  }

  def ok = {
    set("user", session.getAs[OAuth2User]("user"))
    set("backlog", session.getAs[BacklogUser]("user"))
    render("/backlog/ok")
  }

}


text:
'use strict';

// Configuring the Articles module
//angular.module('ustodooris').run(['Menus',
//	function(Menus) {
//		// Set top bar menu items
//		Menus.addMenuItem('topbar', 'Ustodooris', 'ustodooris', 'dropdown', '/ustodooris(/create)?');
//		Menus.addSubMenuItem('topbar', 'ustodooris', 'List Ustodooris', 'ustodooris');
//		Menus.addSubMenuItem('topbar', 'ustodooris', 'New Ustodoori', 'ustodooris/create');
//	}
//]);


text:
#ifndef __DEVICECONTEXT_H__
#define __DEVICECONTEXT_H__

// device context support for gui stuff
//

#include "Rectangle.h"
#include "../renderer/Font.h"

const int VIRTUAL_WIDTH = 640;
const int VIRTUAL_HEIGHT = 480;
const int BLINK_DIVISOR = 200;

class idDeviceContext {
public:
	idDeviceContext();
	~idDeviceContext() { }

	void				Init();
	void				Shutdown();
	bool				Initialized() { return initialized; }
	void				EnableLocalization();

	void				GetTransformInfo(idVec3& origin, idMat3& mat );

	void				SetTransformInfo(const idVec3 &origin, const idMat3 &mat);
	void				DrawMaterial(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex = 1.0, float scaley = 1.0);
	void				DrawRect(float x, float y, float width, float height, float size, const idVec4 &color);
	void				DrawFilledRect(float x, float y, float width, float height, const idVec4 &color);
	int					DrawText(const char *text, float textScale, int textAlign, idVec4 color, idRectangle rectDraw, bool wrap, int cursor = -1, bool calcOnly = false, idList<int> *breaks = NULL, int limit = 0 );
	void				DrawMaterialRect( float x, float y, float w, float h, float size, const idMaterial *mat, const idVec4 &color);
	void				DrawStretchPic(float x, float y, float w, float h, float s0, float t0, float s1, float t1, const idMaterial *mat);
	void				DrawMaterialRotated(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex = 1.0, float scaley = 1.0, float angle = 0.0f);
	void				DrawStretchPicRotated(float x, float y, float w, float h, float s0, float t0, float s1, float t1, const idMaterial *mat, float angle = 0.0f);
	void				DrawWinding( idWinding & w, const idMaterial * mat );

	int					CharWidth( const char c, float scale );
	int					TextWidth(const char *text, float scale, int limit);
	int					TextHeight(const char *text, float scale, int limit);
	int					MaxCharHeight(float scale);
	int					MaxCharWidth(float scale);

	idRegion *			GetTextRegion(const char *text, float textScale, idRectangle rectDraw, float xStart, float yStart);

	void				SetSize( float width, float height );
	void				SetOffset( float x, float y );

	const idMaterial *	GetScrollBarImage(int index);

	void				DrawCursor(float *x, float *y, float size);
	void				SetCursor(int n);

	// clipping rects
	virtual bool		ClippedCoords(float *x, float *y, float *w, float *h, float *s1, float *t1, float *s2, float *t2);
	virtual void		PushClipRect(idRectangle r);
	virtual void		PopClipRect();
	virtual void		EnableClipping(bool b);

	void				SetFont( idFont * font ) { activeFont = font; }

	void				SetOverStrike(bool b) { overStrikeMode = b; }

	bool				GetOverStrike() { return overStrikeMode; }

	void				DrawEditCursor(float x, float y, float scale);

	enum {
		CURSOR_ARROW,
		CURSOR_HAND,
		CURSOR_HAND_JOY1,
		CURSOR_HAND_JOY2,
		CURSOR_HAND_JOY3,
		CURSOR_HAND_JOY4,
		CURSOR_COUNT
	};

	enum {
		ALIGN_LEFT,
		ALIGN_CENTER,
		ALIGN_RIGHT
	};

	enum {
		SCROLLBAR_HBACK,
		SCROLLBAR_VBACK,
		SCROLLBAR_THUMB,
		SCROLLBAR_RIGHT,
		SCROLLBAR_LEFT,
		SCROLLBAR_UP,
		SCROLLBAR_DOWN,
		SCROLLBAR_COUNT
	};

	static idVec4 colorPurple;
	static idVec4 colorOrange;
	static idVec4 colorYellow;
	static idVec4 colorGreen;
	static idVec4 colorBlue;
	static idVec4 colorRed;
	static idVec4 colorWhite;
	static idVec4 colorBlack;
	static idVec4 colorNone;

protected:
	virtual int			DrawText( float x, float y, float scale, idVec4 color, const char *text, float adjust, int limit, int style, int cursor = -1);
	void				PaintChar( float x, float y, const scaledGlyphInfo_t & glyphInfo );
	void				Clear();

	const idMaterial *	cursorImages[CURSOR_COUNT];
	const idMaterial *	scrollBarImages[SCROLLBAR_COUNT];
	const idMaterial *	whiteImage;
	idFont *			activeFont;

	float				xScale;
	float				yScale;
	float				xOffset;
	float				yOffset;

	int					cursor;

	idList<idRectangle>	clipRects;

	bool				enableClipping;

	bool				overStrikeMode;

	idMat3				mat;
	bool				matIsIdentity;
	idVec3				origin;
	bool				initialized;
};

class idDeviceContextOptimized : public idDeviceContext {

	virtual bool		ClippedCoords(float *x, float *y, float *w, float *h, float *s1, float *t1, float *s2, float *t2);
	virtual void		PushClipRect(idRectangle r);
	virtual void		PopClipRect();
	virtual void		EnableClipping(bool b);

	virtual int			DrawText( float x, float y, float scale, idVec4 color, const char *text, float adjust, int limit, int style, int cursor = -1);

	float				clipX1;
	float				clipX2;
	float				clipY1;
	float				clipY2;
};

#endif /* !__DEVICECONTEXT_H__ */


text:
package October.week4;

import java.util.Arrays;

/*

 * explain:
 * Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings.

For example,
Given [[0, 30],[5, 10],[15, 20]],
return false.

 * url:
https://leetcode.com/problems/meeting-rooms/description/
 * solution:

*/
public class CanAttendMeetings {
    public class Interval {
        int start;
        int end;
        Interval() { start = 0; end = 0; }
        Interval(int s, int e) { start = s; end = e; }
    }

    public boolean canAttendMeetings(Interval[] intervals) {
        if (intervals == null) return false;

        Arrays.sort(intervals, (x, y) -> x.start - y.start);
        for (int i = 1; i < intervals.length; i++) {
            if (intervals[i].start < intervals[i-1].end) {
                return false;
            }
        }

        return true;
    }

}


text:
package de.codecentric.resilient.connote;

import de.mrbw.chaos.monkey.EnableChaosMonkey;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.sleuth.Sampler;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;
import de.codecentric.resilient.configuration.DefautConfiguration;

/**
 * Connote Service
 * @author Benjamin Wilms
 */
@EnableChaosMonkey
@EnableDiscoveryClient
@EnableAutoConfiguration
@RefreshScope
@SpringBootApplication
@Import(DefautConfiguration.class)
@EntityScan(basePackageClasses = {ConnoteServiceApplication.class, Jsr310JpaConverters.class})
public class ConnoteServiceApplication {

    @Bean
    public Sampler sampler(){
        return new AlwaysSampler();
    }

    public static void main(String[] args) {
        SpringApplication.run(ConnoteServiceApplication.class, args);
    }
}


text:
package org.apache.calcite.rel.metadata;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
 * Test cases for {@link RelMdUtil}.
 */
public class RelMdUtilTest {

  @Test void testNumDistinctVals() {
    // the first element must be distinct, the second one has half chance of being distinct
    assertEquals(1.5, RelMdUtil.numDistinctVals(2.0, 2.0), 1e-5);

    // when no selection is made, we get no distinct value
    double domainSize = 100;
    assertEquals(0, RelMdUtil.numDistinctVals(domainSize, 0.0), 1e-5);

    // when we perform one selection, we always have 1 distinct value,
    // regardless of the domain size
    for (double dSize = 1; dSize < 100; dSize += 1) {
      assertEquals(1.0, RelMdUtil.numDistinctVals(dSize, 1.0), 1e-5);
    }

    // when we select n objects from a set with n values
    // we get no more than n distinct values
    for (double dSize = 1; dSize < 100; dSize += 1) {
      assertTrue(RelMdUtil.numDistinctVals(dSize, dSize) <= dSize);
    }

    // when the number of selections is large enough
    // we get all distinct values, w.h.p.
    assertEquals(domainSize, RelMdUtil.numDistinctVals(domainSize, domainSize * 100), 1e-5);
  }

}


text:
using Sdl.Web.Common.Models;

namespace Sdl.Web.Common.Interfaces
{
    public interface IContentResolver
    {
        string DefaultExtensionLessPageName { get; set; }
        string DefaultPageName { get; set; }
        string DefaultExtension { get; set; }
        string ResolveLink(object linkData, object resolveInstruction = null);
        object ResolveContent(object content, object resolveInstruction = null);
        MvcData ResolveMvcData(object data);
    }
}


text:
function [ output_args ] = ODEsim_PlotAni( input_args )
%ODESIM_PLOTANI Summary of this function goes here
%   Detailed explanation goes here

end


text:
package org.wso2.developerstudio.eclipse.esb.mediators;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.common.util.Enumerator;

/**
 *
 * A representation of the literals of the enumeration 'Enrich Source Type',
 * and utility methods for working with them.
 *
 * @see org.wso2.developerstudio.eclipse.esb.mediators.MediatorsPackage#getEnrichSourceType()
 * @model
 * @generated
 */
public enum EnrichSourceType implements Enumerator {
	/**
	 * The 'CUSTOM' literal object.
	 *
	 *
	 * @see #CUSTOM_VALUE
	 * @generated
	 * @ordered
	 */
	CUSTOM(0, "CUSTOM", "custom"),

	/**
	 * The 'ENVELOPE' literal object.
	 *
	 *
	 * @see #ENVELOPE_VALUE
	 * @generated
	 * @ordered
	 */
	ENVELOPE(1, "ENVELOPE", "envelope"),

	/**
	 * The 'BODY' literal object.
	 *
	 *
	 * @see #BODY_VALUE
	 * @generated
	 * @ordered
	 */
	BODY(2, "BODY", "body"),

	/**
	 * The 'PROPERTY' literal object.
	 *
	 *
	 * @see #PROPERTY_VALUE
	 * @generated
	 * @ordered
	 */
	PROPERTY(3, "PROPERTY", "property"),

	/**
	 * The 'INLINE' literal object.
	 *
	 *
	 * @see #INLINE_VALUE
	 * @generated
	 * @ordered
	 */
	INLINE(4, "INLINE", "inline");

	/**
	 * The 'CUSTOM' literal value.
	 *
	 *

	 * If the meaning of 'Custom' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #CUSTOM
	 * @model literal="custom"
	 * @generated
	 * @ordered
	 */
	public static final int CUSTOM_VALUE = 0;

	/**
	 * The 'ENVELOPE' literal value.
	 *
	 *

	 * If the meaning of 'Envelope' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #ENVELOPE
	 * @model literal="envelope"
	 * @generated
	 * @ordered
	 */
	public static final int ENVELOPE_VALUE = 1;

	/**
	 * The 'BODY' literal value.
	 *
	 *

	 * If the meaning of 'Body' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #BODY
	 * @model literal="body"
	 * @generated
	 * @ordered
	 */
	public static final int BODY_VALUE = 2;

	/**
	 * The 'PROPERTY' literal value.
	 *
	 *

	 * If the meaning of 'Property' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #PROPERTY
	 * @model literal="property"
	 * @generated
	 * @ordered
	 */
	public static final int PROPERTY_VALUE = 3;

	/**
	 * The 'INLINE' literal value.
	 *
	 *

	 * If the meaning of 'Inline' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #INLINE
	 * @model literal="inline"
	 * @generated
	 * @ordered
	 */
	public static final int INLINE_VALUE = 4;

	/**
	 * An array of all the 'Enrich Source Type' enumerators.
	 *
	 *
	 * @generated
	 */
	private static final EnrichSourceType[] VALUES_ARRAY =
		new EnrichSourceType[] {
			CUSTOM,
			ENVELOPE,
			BODY,
			PROPERTY,
			INLINE,
		};

	/**
	 * A public read-only list of all the 'Enrich Source Type' enumerators.
	 *
	 *
	 * @generated
	 */
	public static final List<EnrichSourceType> VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY));

	/**
	 * Returns the 'Enrich Source Type' literal with the specified literal value.
	 *
	 *
	 * @generated
	 */
	public static EnrichSourceType get(String literal) {
		for (int i = 0; i < VALUES_ARRAY.length; ++i) {
			EnrichSourceType result = VALUES_ARRAY[i];
			if (result.toString().equals(literal)) {
				return result;
			}
		}
		return null;
	}

	/**
	 * Returns the 'Enrich Source Type' literal with the specified name.
	 *
	 *
	 * @generated
	 */
	public static EnrichSourceType getByName(String name) {
		for (int i = 0; i < VALUES_ARRAY.length; ++i) {
			EnrichSourceType result = VALUES_ARRAY[i];
			if (result.getName().equals(name)) {
				return result;
			}
		}
		return null;
	}

	/**
	 * Returns the 'Enrich Source Type' literal with the specified integer value.
	 *
	 *
	 * @generated
	 */
	public static EnrichSourceType get(int value) {
		switch (value) {
			case CUSTOM_VALUE: return CUSTOM;
			case ENVELOPE_VALUE: return ENVELOPE;
			case BODY_VALUE: return BODY;
			case PROPERTY_VALUE: return PROPERTY;
			case INLINE_VALUE: return INLINE;
		}
		return null;
	}

	/**
	 *
	 *
	 * @generated
	 */
	private final int value;

	/**
	 *
	 *
	 * @generated
	 */
	private final String name;

	/**
	 *
	 *
	 * @generated
	 */
	private final String literal;

	/**
	 * Only this class can construct instances.
	 *
	 *
	 * @generated
	 */
	private EnrichSourceType(int value, String name, String literal) {
		this.value = value;
		this.name = name;
		this.literal = literal;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public int getValue() {
	  return value;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public String getName() {
	  return name;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public String getLiteral() {
	  return literal;
	}

	/**
	 * Returns the literal value of the enumerator, which is its string representation.
	 *
	 *
	 * @generated
	 */

	@Override
	public String toString() {
		return literal;
	}

} //EnrichSourceType


text:
<!DOCTYPE html>
<!-- saved from url=(0032)http://fengyizhu.com/project/p5/ -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="UTF-8">
    <title>points</title>
    <script src="p5.js" type="text/javascript"></script><style type="text/css"></style>

    <script src="p5.dom.js" type="text/javascript"></script>
    <script src="p5.sound.js" type="text/javascript"></script>

    <script src="sketch.js" type="text/javascript"></script>

    <style> body {padding: 0; margin: 0;} canvas {vertical-align: top;} </style>
  </head>
  <body></body>
</html>


text:
<?php

namespace Openl10n\Cli\ServiceContainer\Configuration;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class ConfigurationTree implements ConfigurationInterface
{
    /**
     * @var array
     */
    protected $extensions;

    public function __construct(array $extensions)
    {
        $this->extensions = $extensions;
    }

    /**
     * @return TreeBuilder
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('openl10n');

        foreach ($this->extensions as $extension) {
            $rootName = $extension->getName();

            $node = $rootNode->children()->arrayNode($rootName);

            $extension->configure($node);
        }

        return $treeBuilder;
    }
}


text:
                <form id="gform" #contactForm="ngForm">

SAY HELLO:

                    <textarea name="Textarea" [(ngModel)]="contact.textarea" class="contact-textarea block" placeholder="Write your message." required></textarea>

                        YOUR EMAIL
                        <input type="email" id="email" name="Email" [(ngModel)]="contact.email" required>

                    SEND
                </form>

Thank youfor your message!

YOUR CONTACT:

Arnaud Cathala

Vacillating between different diagnosis levels?

Ask us for advice.

Just a question?

We will try to answer it.

You benefited from one of our trainings or accompanying courses?

Give us your feedbacks.

        PLEASE ENTER YOUR EMAIL BEFORE SENDING THE MESSAGE


text:
package org.mifos.test.acceptance.client;

import org.junit.Assert;
import org.mifos.framework.util.DbUnitUtilities;
import org.mifos.test.acceptance.framework.ClientsAndAccountsHomepage;
import org.mifos.test.acceptance.framework.MifosPage;
import org.mifos.test.acceptance.framework.UiTestCaseBase;
import org.mifos.test.acceptance.framework.admin.AdminPage;
import org.mifos.test.acceptance.questionnaire.EditQuestionPage;
import org.mifos.test.acceptance.questionnaire.QuestionDetailPage;
import org.mifos.test.acceptance.questionnaire.ViewAllQuestionsPage;
import org.mifos.test.acceptance.framework.client.ClientEditMFIPage;
import org.mifos.test.acceptance.framework.client.ClientEditMFIParameters;
import org.mifos.test.acceptance.framework.client.ClientEditMFIPreviewPage;
import org.mifos.test.acceptance.framework.client.ClientSearchResultsPage;
import org.mifos.test.acceptance.framework.client.ClientViewDetailsPage;
import org.mifos.test.acceptance.framework.client.CreateClientEnterMfiDataPage;
import org.mifos.test.acceptance.framework.client.CreateClientEnterPersonalDataPage;
import org.mifos.test.acceptance.framework.client.QuestionGroup;
import org.mifos.test.acceptance.framework.testhelpers.CustomPropertiesHelper;
import org.mifos.test.acceptance.framework.testhelpers.NavigationHelper;
import org.mifos.test.acceptance.questionnaire.Choice;
import org.mifos.test.acceptance.questionnaire.CreateQuestionGroupPage;
import org.mifos.test.acceptance.questionnaire.CreateQuestionGroupParameters;
import org.mifos.test.acceptance.questionnaire.CreateQuestionPage;
import org.mifos.test.acceptance.questionnaire.CreateQuestionParameters;
import org.mifos.test.acceptance.questionnaire.QuestionGroupResponsePage;
import org.mifos.test.acceptance.questionnaire.QuestionnairePage;
import org.mifos.test.acceptance.questionnaire.ViewQuestionResponseDetailPage;
import org.mifos.test.acceptance.remote.InitializeApplicationRemoteTestingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.test.context.ContextConfiguration;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import static java.util.Arrays.asList;

@ContextConfiguration(locations = {"classpath:ui-test-context.xml"})
@Test(sequential = true, groups = {"client", "acceptance", "ui", "smoke"})
public class ClientTest extends UiTestCaseBase {

    private NavigationHelper navigationHelper;
    CustomPropertiesHelper propertiesHelper;

    @Autowired
    private DriverManagerDataSource dataSource;
    @Autowired
    private DbUnitUtilities dbUnitUtilities;
    @Autowired
    private InitializeApplicationRemoteTestingService initRemote;
    private Random random;
    private static final String FREE_TEXT = "Free Text";
    public static final String MULTI_SELECT = "Multi Select";
    public static final String EXPECTED_DATE_FORMAT = "%02d/%02d/%04d";
    public static final String NUMBER = "Number";
    public static final String SMART_SELECT = "Smart Select";
    private String questionGroupTitle;
    private String question1;
    private String question2;
    private String response;
    private ClientViewDetailsPage viewClientDetailsPage;
    private Map<Integer, QuestionGroup> questionGroupInstancesOfClient;

    @Override
    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    // one of the dependent methods throws Exception
    @BeforeMethod(alwaysRun = true)
    public void setUp() throws Exception {
        super.setUp();
        navigationHelper = new NavigationHelper(selenium);
        propertiesHelper = new CustomPropertiesHelper(selenium);
        random = new Random();
    }

    @AfterMethod(alwaysRun = true)
    public void logOut() {
        (new MifosPage(selenium)).logout();
    }

    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    public void createClientAndChangeStatusTest() throws Exception {
        initRemote.dataLoadAndCacheRefresh(dbUnitUtilities,
                "acceptance_small_003_dbunit.xml",
                dataSource, selenium);

        ClientsAndAccountsHomepage clientsAndAccountsPage = navigationHelper.navigateToClientsAndAccountsPage();

        ClientViewDetailsPage clientDetailsPage = clientsAndAccountsPage.createClientAndVerify("Joe1233171679953 Guy1233171679953", "MyOffice1233171674227");

        clientsAndAccountsPage.changeCustomerStatus(clientDetailsPage);
    }

    // implementation of test described in issue 2454
    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    public void searchForClientAndEditDetailsTest() throws Exception {
        initRemote.dataLoadAndCacheRefresh(dbUnitUtilities,
                "acceptance_small_003_dbunit.xml",
                dataSource, selenium);

        ClientsAndAccountsHomepage clientsPage = navigationHelper.navigateToClientsAndAccountsPage();
        ClientSearchResultsPage searchResultsPage = clientsPage.searchForClient("Stu1232993852651");
        searchResultsPage.verifyPage();
        ClientViewDetailsPage clientDetailsPage = searchResultsPage.navigateToSearchResult("Stu1232993852651 Client1232993852651: ID 0002-000000003");

        ClientEditMFIPage editMFIPage = clientDetailsPage.navigateToEditMFIPage();
        editMFIPage.verifyPage();

        ClientEditMFIParameters params = new ClientEditMFIParameters();
        params.setExternalId("extID123");
        params.setTrainedDateDD("15");
        params.setTrainedDateMM("12");
        params.setTrainedDateYYYY("2008");

        ClientEditMFIPreviewPage mfiPreviewPage = editMFIPage.submitAndNavigateToClientEditMFIPreviewPage(params);
        mfiPreviewPage.verifyPage();
        clientDetailsPage = mfiPreviewPage.submit();
        assertTextFoundOnPage("extID123");
        assertTextFoundOnPage("15/12/2008");
    }

    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    @Test(groups = {"smoke"})
    public void createClientWithCorrectAgeTest() throws Exception {
        initRemote.dataLoadAndCacheRefresh(dbUnitUtilities,
                "acceptance_small_003_dbunit.xml",
                dataSource, selenium);
        propertiesHelper.setMinimumAgeForClients(18);
        propertiesHelper.setMaximumAgeForClients(60);
        ClientsAndAccountsHomepage clientsAndAccountsPage = navigationHelper.navigateToClientsAndAccountsPage();
        CreateClientEnterPersonalDataPage clientPersonalDataPage = clientsAndAccountsPage.createClient("MyOffice1233171674227", "11", "12", "1987");
        CreateClientEnterMfiDataPage nextPage = clientPersonalDataPage.submitAndGotoCreateClientEnterMfiDataPage();
        nextPage.verifyPage("CreateClientMfiInfo");
    }

    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    public void createClientWithMoreThanMaximumAgeTest() throws Exception {
        initRemote.dataLoadAndCacheRefresh(dbUnitUtilities,
                "acceptance_small_003_dbunit.xml",
                dataSource, selenium);
        propertiesHelper.setMinimumAgeForClients(18);
        propertiesHelper.setMaximumAgeForClients(60);
        ClientsAndAccountsHomepage clientsAndAccountsPage = navigationHelper.navigateToClientsAndAccountsPage();
        CreateClientEnterPersonalDataPage clientPersonalDataPage = clientsAndAccountsPage.createClient("MyOffice1233171674227", "11", "12", "1940");
        CreateClientEnterPersonalDataPage nextPage = clientPersonalDataPage.dontLoadNext();
        nextPage.verifyPage("CreateClientPersonalInfo");
    }

    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    public void createClientWithLessThanMinimumAgeTest() throws Exception {
        initRemote.dataLoadAndCacheRefresh(dbUnitUtilities,
                "acceptance_small_003_dbunit.xml",
                dataSource, selenium);
        propertiesHelper.setMinimumAgeForClients(18);
        propertiesHelper.setMaximumAgeForClients(60);
        ClientsAndAccountsHomepage clientsAndAccountsPage = navigationHelper.navigateToClientsAndAccountsPage();
        CreateClientEnterPersonalDataPage clientPersonalDataPage = clientsAndAccountsPage.createClient("MyOffice1233171674227", "11", "12", "1995");
        CreateClientEnterPersonalDataPage nextPage = clientPersonalDataPage.dontLoadNext();
        nextPage.verifyPage("CreateClientPersonalInfo");
    }

    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    public void searchForClientAndAddSurveysTest() throws Exception {
        initRemote.dataLoadAndCacheRefresh(dbUnitUtilities, "acceptance_small_003_dbunit.xml", dataSource, selenium);

        createQuestionGroup();
        navigateToClientDetailsPage();

        testAttachQuestionGroup(response);
        verifyQuestionGroupInstanceListing(1);
        verifyQuestionGroupResponse(response);

        testEditQuestionGroup(response + 1);
        verifyQuestionGroupInstanceListing(2);
        verifyQuestionGroupResponse(response +1);

        testShouldEditInactiveQuestion(response + 2);
        verifyQuestionGroupInstanceListing(3);
        verifyQuestionGroupResponse(response +2);

        testSectionShouldNotAppearInQuestionnaireWhenAllQuestionsAreInactive();
    }

    private void testSectionShouldNotAppearInQuestionnaireWhenAllQuestionsAreInactive() {
        testActivateQuestion(question1);
        testDeactivateQuestion(question2);
        navigateToClientDetailsPage();
        viewClientDetailsPage.getQuestionnairePage(questionGroupTitle);
        Assert.assertFalse("Section2 should not be present on questionnaire when all questions are inactive",
                selenium.isTextPresent("Section2"));
    }

    private void testShouldEditInactiveQuestion(String response) {
        testDeactivateQuestion(question1);
        navigateToClientDetailsPage();
        testEditQuestionGroup(response);
    }

    private void testDeactivateQuestion(String question) {
        AdminPage adminPage = navigationHelper.navigateToAdminPage();
        ViewAllQuestionsPage viewAllQuestionsPage = adminPage.navigateToViewAllQuestions();
        QuestionDetailPage questionDetailPage = viewAllQuestionsPage.navigateToQuestionDetail(question);
        EditQuestionPage editQuestionPage = questionDetailPage.navigateToEditQuestionPage();
        questionDetailPage = editQuestionPage.deactivate();
    }

    private void testActivateQuestion(String question) {
        AdminPage adminPage = navigationHelper.navigateToAdminPage();
        ViewAllQuestionsPage viewAllQuestionsPage = adminPage.navigateToViewAllQuestions();
        QuestionDetailPage questionDetailPage = viewAllQuestionsPage.navigateToQuestionDetail(question);
        EditQuestionPage editQuestionPage = questionDetailPage.navigateToEditQuestionPage();
        questionDetailPage = editQuestionPage.activate();
    }

    private void testEditQuestionGroup(String answer) {
        int instanceId = latestInstanceId(questionGroupInstancesOfClient);
        QuestionGroupResponsePage questionGroupResponsePage = viewClientDetailsPage.navigateToQuestionGroupResponsePage(instanceId);
        QuestionnairePage questionnairePage = questionGroupResponsePage.navigateToEditResponses();
        verifyCancel(questionnairePage);
        questionGroupResponsePage = viewClientDetailsPage.navigateToQuestionGroupResponsePage(instanceId);
        questionnairePage = questionGroupResponsePage.navigateToEditResponses();
        questionnairePage.setResponse(question1, answer);
        MifosPage mifosPage = questionnairePage.submit();
        Assert.assertTrue(mifosPage instanceof ClientViewDetailsPage);
        ClientViewDetailsPage clientViewDetailsPage = (ClientViewDetailsPage) mifosPage;
        clientViewDetailsPage.verifyPage();
        viewClientDetailsPage = clientViewDetailsPage;
    }

    private void verifyQuestionGroupResponse(String response) {
        QuestionGroupResponsePage questionGroupResponsePage = viewClientDetailsPage.navigateToQuestionGroupResponsePage(latestInstanceId(questionGroupInstancesOfClient));
        questionGroupResponsePage.verifyPage();
        String msg = response + " not found for question " + question1 + ". Instead found " + questionGroupResponsePage.getAnswerHtml(question1);
        Assert.assertTrue(msg, questionGroupResponsePage.getAnswerHtml(question1).contains(response));
        Assert.assertTrue(questionGroupResponsePage.getAnswerHtml(question2).contains("Choice1"));
        Assert.assertTrue(questionGroupResponsePage.getAnswerHtml(question2).contains("Choice3"));
        Assert.assertTrue(questionGroupResponsePage.getAnswerHtml(question2).contains("Choice4"));
        viewClientDetailsPage = questionGroupResponsePage.navigateToViewClientDetailsPage();
        viewClientDetailsPage.verifyPage();
    }

    private void verifyQuestionGroupInstanceListing(int expectedSize) {
        questionGroupInstancesOfClient = viewClientDetailsPage.getQuestionGroupInstances();
        QuestionGroup latestInstance = getLatestQuestionGroupInstance();
        Assert.assertEquals(expectedSize, questionGroupInstancesOfClient.size());
        Calendar calendar = Calendar.getInstance();
        String expectedDate = String.format(EXPECTED_DATE_FORMAT, calendar.get(Calendar.DATE), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.YEAR));
        Assert.assertEquals(questionGroupTitle, latestInstance.getName());
        Assert.assertEquals(expectedDate, latestInstance.getDate());
    }

    private QuestionGroup getLatestQuestionGroupInstance() {
        return questionGroupInstancesOfClient.get(latestInstanceId(questionGroupInstancesOfClient));
    }

    private void testAttachQuestionGroup(String response) {
        QuestionnairePage questionnairePage = viewClientDetailsPage.getQuestionnairePage(questionGroupTitle);
        verifyCancel(questionnairePage);
        questionnairePage = checkMandatoryQuestionValidation(questionGroupTitle, question1, question2, viewClientDetailsPage);
        questionnairePage.setResponse(question1, response);
        MifosPage mifosPage = questionnairePage.submit();
        Assert.assertTrue(mifosPage instanceof ClientViewDetailsPage);
        ClientViewDetailsPage clientViewDetailsPage = (ClientViewDetailsPage) mifosPage;
        clientViewDetailsPage.verifyPage();
        viewClientDetailsPage = clientViewDetailsPage;
    }

    private void navigateToClientDetailsPage() {
        ClientsAndAccountsHomepage clientsPage = navigationHelper.navigateToClientsAndAccountsPage();
        ClientSearchResultsPage searchResultsPage = clientsPage.searchForClient("Stu1232993852651");
        searchResultsPage.verifyPage();
        viewClientDetailsPage = searchResultsPage.navigateToSearchResult("Stu1232993852651 Client1232993852651: ID 0002-000000003");
    }

    private void createQuestionGroup() {
        questionGroupTitle = "QG1" + random.nextInt(100);
        question1 = "FT_" + random.nextInt(100);
        question2 = "MS_" + random.nextInt(100);
        response = "Hello World";

        AdminPage adminPage = navigationHelper.navigateToAdminPage();
        CreateQuestionPage createQuestionPage = adminPage.navigateToCreateQuestionPage().verifyPage();
        createQuestionPage.addQuestion(getCreateQuestionParams(question1, FREE_TEXT, null));
        createQuestionPage.addQuestion(getCreateQuestionParams(question2, MULTI_SELECT, asList("Choice1", "Choice2", "Choice3", "Choice4")));
        adminPage = createQuestionPage.submitQuestions();

        CreateQuestionGroupPage createQuestionGroupPage = adminPage.navigateToCreateQuestionGroupPage().verifyPage();
        CreateQuestionGroupParameters parameters;
        parameters = getCreateQuestionGroupParameters(questionGroupTitle, asList(question1), "View Client", "Section1");
        createQuestionGroupPage.addSection(parameters);
        createQuestionGroupPage.markEveryOtherQuestionsMandatory(asList(question1));
        parameters = getCreateQuestionGroupParameters(questionGroupTitle, asList(question2), "View Client", "Section2");
        createQuestionGroupPage.addSection(parameters);
        createQuestionGroupPage.submit(parameters);
    }

    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    public void createClientWithQuestionGroups() throws Exception {
        initRemote.dataLoadAndCacheRefresh(dbUnitUtilities, "acceptance_small_003_dbunit.xml", dataSource, selenium);

        String questionGroupTitle = "QG1" + random.nextInt(100);
        String question1 = "NU_" + random.nextInt(100);
        String question2 = "SS_" + random.nextInt(100);
        String answer = "30";
        List<Choice> choices = asList(new Choice("Choice1", asList("Tag1", "Tag2")), new Choice("Choice2", asList("Tag3", "Tag4")));

        createQuestionGroupForCreateClient(questionGroupTitle, question1, question2, choices);
        ClientsAndAccountsHomepage clientsAndAccountsPage = navigationHelper.navigateToClientsAndAccountsPage();

        ClientViewDetailsPage clientDetailsPage = clientsAndAccountsPage.createClientWithQuestionGroups("Joe1233171679953 Guy1233171679953",
                                                "MyOffice1233171674227", getChoiceTags(), answer);
        ViewQuestionResponseDetailPage responseDetailPage = clientDetailsPage.navigateToViewAdditionalInformationPage();
        responseDetailPage.verifyQuestionPresent(question1, answer);
        responseDetailPage.verifyQuestionPresent(question2, "Choice1", "Choice2");
        responseDetailPage.navigateToDetailsPage();
        clientDetailsPage.verifyPage();
    }

    private Map<String, String> getChoiceTags() {
        Map<String,String> tags = new HashMap<String, String>();
        tags.put("Tag1", "Choice1");
        tags.put("Tag3", "Choice2");
        return tags;
    }

    private QuestionnairePage checkMandatoryQuestionValidation(String questionGroupTitle, String question1, String question2, ClientViewDetailsPage viewDetailsPage) {
        QuestionnairePage questionnairePage = viewDetailsPage.getQuestionnairePage(questionGroupTitle);
        questionnairePage.setResponsesForMultiSelect(question2, 4, "Choice1", "Choice3", "Choice4");
        MifosPage mifosPage = questionnairePage.submit();
        Assert.assertTrue(mifosPage instanceof QuestionnairePage);
        questionnairePage = (QuestionnairePage) mifosPage;
        Assert.assertTrue(questionnairePage.isErrorPresent("Please specify " + question1));
        return questionnairePage;
    }

    private ClientViewDetailsPage verifyCancel(QuestionnairePage questionnairePage) {
        ClientViewDetailsPage viewDetailsPage = questionnairePage.cancel();
        viewDetailsPage.verifyPage();
        return viewDetailsPage;
    }

    public Integer latestInstanceId(Map<Integer, QuestionGroup> questionGroups) {
        Set<Integer> keys = questionGroups.keySet();
        return Collections.max(keys);
    }

    private void createQuestionGroupForCreateClient(String qgTitle, String q1, String q2, List<Choice> choiceTags) {
        AdminPage adminPage = navigationHelper.navigateToAdminPage();
        CreateQuestionPage cqPage = adminPage.navigateToCreateQuestionPage().verifyPage();
        cqPage.addQuestion(getCreateQuestionParams(q1, NUMBER, 10, 100, null));
        cqPage.addQuestion(getCreateQuestionParams(q2, SMART_SELECT, null, null, choiceTags));
        adminPage = cqPage.submitQuestions();

        CreateQuestionGroupPage cqGroupPage = adminPage.navigateToCreateQuestionGroupPage().verifyPage();
        CreateQuestionGroupParameters parameters = getCreateQuestionGroupParameters(qgTitle, asList(q1, q2), "Create Client", "Section1");
        cqGroupPage.addSection(parameters);
        cqGroupPage.markEveryOtherQuestionsMandatory(asList(q1));
        cqGroupPage.submit(parameters);
    }

    private CreateQuestionGroupParameters getCreateQuestionGroupParameters(String questionGroupTitle, List<String> questions, String appliesTo, String sectionName) {
        CreateQuestionGroupParameters parameters = new CreateQuestionGroupParameters();
        parameters.setTitle(questionGroupTitle);
        parameters.setAppliesTo(appliesTo);
        parameters.setAnswerEditable(true);
        parameters.setSectionName(sectionName);
        parameters.setQuestions(questions);
        return parameters;
    }

    private CreateQuestionParameters getCreateQuestionParams(String title, String type, List<String> choices) {
        CreateQuestionParameters parameters = new CreateQuestionParameters();
        parameters.setText(title);
        parameters.setType(type);
        parameters.setChoicesFromStrings(choices);
        return parameters;
    }

    private CreateQuestionParameters getCreateQuestionParams(String title, String type, Integer numericMin, Integer numericMax, List<Choice> choices) {
        CreateQuestionParameters parameters = new CreateQuestionParameters();
        parameters.setText(title);
        parameters.setType(type);
        parameters.setChoices(choices);
        parameters.setNumericMin(numericMin);
        parameters.setNumericMax(numericMax);
        return parameters;
    }

}