text:
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "../BasicTypes.h"
#include "../HAL/UnrealMemory.h"
#include "../Templates/IsTriviallyCopyConstructible.h"
#include "../Templates/UnrealTypeTraits.h"
#include "../Templates/UnrealTemplate.h"
#include "../Templates/IsTriviallyDestructible.h"
#include "ContainerAllocationPolicies.h"
#include "TArray.h"
#include "../Math/UnrealMathUtility.h"
#include "ScriptArray.h"
#include "BitArray.h"

#define TSPARSEARRAY_RANGED_FOR_CHECKS 1

// Forward declarations.
template<typename ElementType,typename Allocator = FDefaultSparseArrayAllocator >
class TSparseArray;

/** The result of a sparse array allocation. */
struct FSparseArrayAllocationInfo
{
	int32 Index;
	void* Pointer;
};

/** Allocated elements are overlapped with free element info in the element list. */
template<typename ElementType>
union TSparseArrayElementOrFreeListLink
{
	/** If the element is allocated, its value is stored here. */
	ElementType ElementData;

	struct
	{
		/** If the element isn't allocated, this is a link to the previous element in the array's free list. */
		int32 PrevFreeIndex;

		/** If the element isn't allocated, this is a link to the next element in the array's free list. */
		int32 NextFreeIndex;
	};
};

class FScriptSparseArray;

/**
 * A dynamically sized array where element indices aren't necessarily contiguous.  Memory is allocated for all
 * elements in the array's index range, so it doesn't save memory; but it does allow O(1) element removal that
 * doesn't invalidate the indices of subsequent elements.  It uses TArray to store the elements, and a TBitArray
 * to store whether each element index is allocated (for fast iteration over allocated elements).
 *
 **/
template<typename InElementType,typename Allocator /*= FDefaultSparseArrayAllocator */>
class TSparseArray
{
	using ElementType = InElementType;

	friend struct TContainerTraits<TSparseArray>;
	friend class  FScriptSparseArray;

public:

	/** Destructor. */
	~TSparseArray()
	{
		// Destruct the elements in the array.
		Empty();
	}

	/** Marks an index as allocated, and returns information about the allocation. */
	FSparseArrayAllocationInfo AllocateIndex(int32 Index)
	{
		check(Index >= 0);
		check(Index < GetMaxIndex());
		check(!AllocationFlags[Index]);

		// Flag the element as allocated.
		AllocationFlags[Index] = true;

		// Set the allocation info.
		FSparseArrayAllocationInfo Result;
		Result.Index = Index;
		Result.Pointer = &GetData(Result.Index).ElementData;

		return Result;
	}

	/**
	 * Allocates space for an element in the array.  The element is not initialized, and you must use the corresponding placement new operator
	 * to construct the element in the allocated memory.
	 */
	FSparseArrayAllocationInfo AddUninitialized()
	{
		int32 Index;
		if(NumFreeIndices)
		{
			// Remove and use the first index from the list of free elements.
			Index = FirstFreeIndex;
			FirstFreeIndex = GetData(FirstFreeIndex).NextFreeIndex;
			--NumFreeIndices;
			if(NumFreeIndices)
			{
				GetData(FirstFreeIndex).PrevFreeIndex = -1;
			}
		}
		else
		{
			// Add a new element.
			Index = Data.AddUninitialized(1);
			AllocationFlags.Add(false);
		}

		return AllocateIndex(Index);
	}

	/** Adds an element to the array. */
	int32 Add(typename TTypeTraits<ElementType>::ConstInitType Element)
	{
		FSparseArrayAllocationInfo Allocation = AddUninitialized();
		new(Allocation) ElementType(Element);
		return Allocation.Index;
	}

	/**
	 * Allocates space for an element in the array at a given index.  The element is not initialized, and you must use the corresponding placement new operator
	 * to construct the element in the allocated memory.
	 */
	FSparseArrayAllocationInfo InsertUninitialized(int32 Index)
	{
		// Enlarge the array to include the given index.
		if(Index >= Data.Num())
		{
			Data.AddUninitialized(Index + 1 - Data.Num());
			while(AllocationFlags.Num() < Data.Num())
			{
				const int32 FreeIndex = AllocationFlags.Num();
				GetData(FreeIndex).PrevFreeIndex = -1;
				GetData(FreeIndex).NextFreeIndex = FirstFreeIndex;
				if(NumFreeIndices)
				{
					GetData(FirstFreeIndex).PrevFreeIndex = FreeIndex;
				}
				FirstFreeIndex = FreeIndex;
				verify(AllocationFlags.Add(false) == FreeIndex);
				++NumFreeIndices;
			};
		}

		// Verify that the specified index is free.
		check(!AllocationFlags[Index]);

		// Remove the index from the list of free elements.
		--NumFreeIndices;
		const int32 PrevFreeIndex = GetData(Index).PrevFreeIndex;
		const int32 NextFreeIndex = GetData(Index).NextFreeIndex;
		if(PrevFreeIndex != -1)
		{
			GetData(PrevFreeIndex).NextFreeIndex = NextFreeIndex;
		}
		else
		{
			FirstFreeIndex = NextFreeIndex;
		}
		if(NextFreeIndex != -1)
		{
			GetData(NextFreeIndex).PrevFreeIndex = PrevFreeIndex;
		}

		return AllocateIndex(Index);
	}

	/**
	 * Inserts an element to the array.
	 */
	void Insert(int32 Index,typename TTypeTraits<ElementType>::ConstInitType Element)
	{
		new(InsertUninitialized(Index)) ElementType(Element);
	}

	/** Removes Count elements from the array, starting from Index. */
	void RemoveAt(int32 Index,int32 Count = 1)
	{
		if (!TIsTriviallyDestructible<ElementType>::Value)
		{
			for (int32 It = Index, ItCount = Count; ItCount; ++It, --ItCount)
			{
				((ElementType&)GetData(It).ElementData).~ElementType();
			}
		}

		RemoveAtUninitialized(Index, Count);
	}

	/** Removes Count elements from the array, starting from Index, without destructing them. */
	void RemoveAtUninitialized(int32 Index,int32 Count = 1)
	{
		for (; Count; --Count)
		{
			check(AllocationFlags[Index]);

			// Mark the element as free and add it to the free element list.
			if(NumFreeIndices)
			{
				GetData(FirstFreeIndex).PrevFreeIndex = Index;
			}
			auto& IndexData = GetData(Index);
			IndexData.PrevFreeIndex = -1;
			IndexData.NextFreeIndex = NumFreeIndices > 0 ? FirstFreeIndex : INDEX_NONE;
			FirstFreeIndex = Index;
			++NumFreeIndices;
			AllocationFlags[Index] = false;

			++Index;
		}
	}

	/**
	 * Removes all elements from the array, potentially leaving space allocated for an expected number of elements about to be added.
	 * @param ExpectedNumElements - The expected number of elements about to be added.
	 */
	void Empty(int32 ExpectedNumElements = 0)
	{
		// Destruct the allocated elements.
		if( !TIsTriviallyDestructible<ElementType>::Value )
		{
			for(TIterator It(*this);It;++It)
			{
				ElementType& Element = *It;
				Element.~ElementType();
			}
		}

		// Free the allocated elements.
		Data.Empty(ExpectedNumElements);
		FirstFreeIndex = -1;
		NumFreeIndices = 0;
		AllocationFlags.Empty(ExpectedNumElements);
	}

	/** Empties the array, but keep its allocated memory as slack. */
	void Reset()
	{
		// Destruct the allocated elements.
		if( !TIsTriviallyDestructible<ElementType>::Value )
		{
			for(TIterator It(*this);It;++It)
			{
				ElementType& Element = *It;
				Element.~ElementType();
			}
		}

		// Free the allocated elements.
		Data.Reset();
		FirstFreeIndex = -1;
		NumFreeIndices = 0;
		AllocationFlags.Reset();
	}

	/**
	 * Preallocates enough memory to contain the specified number of elements.
	 *
	 * @param	ExpectedNumElements		the total number of elements that the array will have
	 */
	void Reserve(int32 ExpectedNumElements)
	{
		if ( ExpectedNumElements > Data.Num() )
		{
			const int32 ElementsToAdd = ExpectedNumElements - Data.Num();

			// allocate memory in the array itself
			int32 ElementIndex = Data.AddUninitialized(ElementsToAdd);

			// now mark the new elements as free
			for ( int32 FreeIndex = ExpectedNumElements - 1; FreeIndex >= ElementIndex; --FreeIndex )
			{
				if(NumFreeIndices)
				{
					GetData(FirstFreeIndex).PrevFreeIndex = FreeIndex;
				}
				GetData(FreeIndex).PrevFreeIndex = -1;
				GetData(FreeIndex).NextFreeIndex = NumFreeIndices > 0 ? FirstFreeIndex : INDEX_NONE;
				FirstFreeIndex = FreeIndex;
				++NumFreeIndices;
			}
			//@fixme - this will have to do until TBitArray has a Reserve method....
			for ( int32 i = 0; i < ElementsToAdd; i++ )
			{
				AllocationFlags.Add(false);
			}
		}
	}

	/** Shrinks the array's storage to avoid slack. */
	void Shrink()
	{
		// Determine the highest allocated index in the data array.
		int32 MaxAllocatedIndex = INDEX_NONE;
		for(TConstSetBitIterator<typename Allocator::BitArrayAllocator> AllocatedIndexIt(AllocationFlags);AllocatedIndexIt;++AllocatedIndexIt)
		{
			MaxAllocatedIndex = FMath::Max(MaxAllocatedIndex,AllocatedIndexIt.GetIndex());
		}

		const int32 FirstIndexToRemove = MaxAllocatedIndex + 1;
		if(FirstIndexToRemove < Data.Num())
		{
			if(NumFreeIndices > 0)
			{
				// Look for elements in the free list that are in the memory to be freed.
				int32 FreeIndex = FirstFreeIndex;
				while(FreeIndex != INDEX_NONE)
				{
					if(FreeIndex >= FirstIndexToRemove)
					{
						const int32 PrevFreeIndex = GetData(FreeIndex).PrevFreeIndex;
						const int32 NextFreeIndex = GetData(FreeIndex).NextFreeIndex;
						if(NextFreeIndex != -1)
						{
							GetData(NextFreeIndex).PrevFreeIndex = PrevFreeIndex;
						}
						if(PrevFreeIndex != -1)
						{
							GetData(PrevFreeIndex).NextFreeIndex = NextFreeIndex;
						}
						else
						{
							FirstFreeIndex = NextFreeIndex;
						}
						--NumFreeIndices;

						FreeIndex = NextFreeIndex;
					}
					else
					{
						FreeIndex = GetData(FreeIndex).NextFreeIndex;
					}
				}
			}

			// Truncate unallocated elements at the end of the data array.
			Data.RemoveAt(FirstIndexToRemove,Data.Num() - FirstIndexToRemove);
			AllocationFlags.RemoveAt(FirstIndexToRemove,AllocationFlags.Num() - FirstIndexToRemove);
		}

		// Shrink the data array.
		Data.Shrink();
	}

	/** Compacts the allocated elements into a contiguous index range. */
	/** Returns true if any elements were relocated, false otherwise. */
	bool Compact()
	{
		int32 NumFree = NumFreeIndices;
		if (NumFree == 0)
		{
			return false;
		}

		bool bResult = false;

		FElementOrFreeListLink* ElementData = Data.GetData();

		int32 EndIndex    = Data.Num();
		int32 TargetIndex = EndIndex - NumFree;
		int32 FreeIndex   = FirstFreeIndex;
		while (FreeIndex != -1)
		{
			int32 NextFreeIndex = GetData(FreeIndex).NextFreeIndex;
			if (FreeIndex < TargetIndex)
			{
				// We need an element here
				do
				{
					--EndIndex;
				}
				while (!AllocationFlags[EndIndex]);

				RelocateConstructItems<FElementOrFreeListLink>(ElementData + FreeIndex, ElementData + EndIndex, 1);
				AllocationFlags[FreeIndex] = true;

				bResult = true;
			}

			FreeIndex = NextFreeIndex;
		}

		Data           .RemoveAt(TargetIndex, NumFree);
		AllocationFlags.RemoveAt(TargetIndex, NumFree);

		NumFreeIndices = 0;
		FirstFreeIndex = -1;

		return bResult;
	}

	/** Compacts the allocated elements into a contiguous index range. Does not change the iteration order of the elements. */
	/** Returns true if any elements were relocated, false otherwise. */
	bool CompactStable()
	{
		if (NumFreeIndices == 0)
		{
			return false;
		}

		// Copy the existing elements to a new array.
		TSparseArray<ElementType,Allocator> CompactedArray;
		CompactedArray.Empty(Num());
		for(TConstIterator It(*this);It;++It)
		{
			new(CompactedArray.AddUninitialized()) ElementType(*It);
		}

		// Replace this array with the compacted array.
		Exchange(*this,CompactedArray);

		return true;
	}

	/**
	 * Helper function to return the amount of memory allocated by this container
	 * @return number of bytes allocated by this container
	 */
	uint32 GetAllocatedSize( void ) const
	{
		return	(Data.Num() + Data.GetSlack()) * sizeof(FElementOrFreeListLink) +
				AllocationFlags.GetAllocatedSize();
	}

	/**
	 * Equality comparison operator.
	 * Checks that both arrays have the same elements and element indices; that means that unallocated elements are signifigant!
	 */
	friend bool operator==(const TSparseArray& A,const TSparseArray& B)
	{
		if(A.GetMaxIndex() != B.GetMaxIndex())
		{
			return false;
		}

		for(int32 ElementIndex = 0;ElementIndex < A.GetMaxIndex();ElementIndex++)
		{
			const bool bIsAllocatedA = A.IsAllocated(ElementIndex);
			const bool bIsAllocatedB = B.IsAllocated(ElementIndex);
			if(bIsAllocatedA != bIsAllocatedB)
			{
				return false;
			}
			else if(bIsAllocatedA)
			{
				if(A[ElementIndex] != B[ElementIndex])
				{
					return false;
				}
			}
		}

		return true;
	}

	/**
	 * Inequality comparison operator.
	 * Checks that both arrays have the same elements and element indices; that means that unallocated elements are signifigant!
	 */
	friend bool operator!=(const TSparseArray& A,const TSparseArray& B)
	{
		return !(A == B);
	}

	/** Default constructor. */
	TSparseArray()
	:	FirstFreeIndex(-1)
	,	NumFreeIndices(0)
	{}

	/** Move constructor. */
	TSparseArray(TSparseArray&& InCopy)
	{
		MoveOrCopy(*this, InCopy);
	}

	/** Copy constructor. */
	TSparseArray(const TSparseArray& InCopy)
	:	FirstFreeIndex(-1)
	,	NumFreeIndices(0)
	{
		*this = InCopy;
	}

	/** Move assignment operator. */
	TSparseArray& operator=(TSparseArray&& InCopy)
	{
		if(this != &InCopy)
		{
			MoveOrCopy(*this, InCopy);
		}
		return *this;
	}

	/** Copy assignment operator. */
	TSparseArray& operator=(const TSparseArray& InCopy)
	{
		if (this != &InCopy)
		{
			int32 SrcMax = InCopy.GetMaxIndex();

			// Reallocate the array.
			Empty(SrcMax);
			Data.AddUninitialized(SrcMax);

			// Copy the other array's element allocation state.
			FirstFreeIndex  = InCopy.FirstFreeIndex;
			NumFreeIndices  = InCopy.NumFreeIndices;
			AllocationFlags = InCopy.AllocationFlags;

			// Determine whether we need per element construction or bulk copy is fine
			if (!TIsTriviallyCopyConstructible<ElementType>::Value)
			{
				      FElementOrFreeListLink* DestData = (FElementOrFreeListLink*)Data.GetData();
				const FElementOrFreeListLink* SrcData  = (FElementOrFreeListLink*)InCopy.Data.GetData();

				// Use the inplace new to copy the element to an array element
				for (int32 Index = 0; Index < SrcMax; ++Index)
				{
					      FElementOrFreeListLink& DestElement = DestData[Index];
					const FElementOrFreeListLink& SrcElement  = SrcData [Index];
					if (InCopy.IsAllocated(Index))
					{
						::new((uint8*)&DestElement.ElementData) ElementType(*(const ElementType*)&SrcElement.ElementData);
					}
					else
					{
						DestElement.PrevFreeIndex = SrcElement.PrevFreeIndex;
						DestElement.NextFreeIndex = SrcElement.NextFreeIndex;
					}
				}
			}
			else
			{
				// Use the much faster path for types that allow it
				FMemory::Memcpy(Data.GetData(), InCopy.Data.GetData(), sizeof(FElementOrFreeListLink) * SrcMax);
			}
		}
		return *this;
	}

private:
	template <typename SparseArrayType>
	FORCEINLINE static typename TEnableIf<TContainerTraits<SparseArrayType>::MoveWillEmptyContainer>::Type MoveOrCopy(SparseArrayType& ToArray, SparseArrayType& FromArray)
	{
		// Destruct the allocated elements.
		if( !TIsTriviallyDestructible<ElementType>::Value )
		{
			for (ElementType& Element : ToArray)
			{
				DestructItem(&Element);
			}
		}

		ToArray.Data            = (DataType&&)FromArray.Data;
		ToArray.AllocationFlags = (AllocationBitArrayType&&)FromArray.AllocationFlags;

		ToArray.FirstFreeIndex = FromArray.FirstFreeIndex;
		ToArray.NumFreeIndices = FromArray.NumFreeIndices;
		FromArray.FirstFreeIndex = -1;
		FromArray.NumFreeIndices = 0;
	}

	template <typename SparseArrayType>
	FORCEINLINE static typename TEnableIf<!TContainerTraits<SparseArrayType>::MoveWillEmptyContainer>::Type MoveOrCopy(SparseArrayType& ToArray, SparseArrayType& FromArray)
	{
		ToArray = FromArray;
	}

public:
	// Accessors.
	ElementType& operator[](int32 Index)
	{
		checkSlow(Index >= 0 && Index < Data.Num() && Index < AllocationFlags.Num());
		//checkSlow(AllocationFlags[Index]); // Disabled to improve loading times -BZ
		return *(ElementType*)&GetData(Index).ElementData;
	}
	const ElementType& operator[](int32 Index) const
	{
		checkSlow(Index >= 0 && Index < Data.Num() && Index < AllocationFlags.Num());
		//checkSlow(AllocationFlags[Index]); // Disabled to improve loading times -BZ
		return *(ElementType*)&GetData(Index).ElementData;
	}

	bool IsAllocated(int32 Index) const { return AllocationFlags[Index]; }
	int32 GetMaxIndex() const { return Data.Num(); }
	int32 Num() const { return Data.Num() - NumFreeIndices; }

	/**
	 * Checks that the specified address is not part of an element within the container.  Used for implementations
	 * to check that reference arguments aren't going to be invalidated by possible reallocation.
	 *
	 * @param Addr The address to check.
	 */
	FORCEINLINE void CheckAddress(const ElementType* Addr) const
	{
		Data.CheckAddress(Addr);
	}

private:

	/** The base class of sparse array iterators. */
	template<bool bConst>
	class TBaseIterator
	{
	public:
		typedef TConstSetBitIterator<typename Allocator::BitArrayAllocator> BitArrayItType;

	private:
		typedef typename TChooseClass<bConst,const TSparseArray,TSparseArray>::Result ArrayType;
		typedef typename TChooseClass<bConst,const ElementType,ElementType>::Result ItElementType;

	public:
		explicit TBaseIterator(ArrayType& InArray, const BitArrayItType& InBitArrayIt)
			: Array     (InArray)
			, BitArrayIt(InBitArrayIt)
		{
		}

		FORCEINLINE TBaseIterator& operator++()
		{
			// Iterate to the next set allocation flag.
			++BitArrayIt;
			return *this;
		}

		FORCEINLINE int32 GetIndex() const { return BitArrayIt.GetIndex(); }

		FORCEINLINE friend bool operator==(const TBaseIterator& Lhs, const TBaseIterator& Rhs) { return Lhs.BitArrayIt == Rhs.BitArrayIt && &Lhs.Array == &Rhs.Array; }
		FORCEINLINE friend bool operator!=(const TBaseIterator& Lhs, const TBaseIterator& Rhs) { return Lhs.BitArrayIt != Rhs.BitArrayIt || &Lhs.Array != &Rhs.Array; }

		/** conversion to "bool" returning true if the iterator is valid. */
		FORCEINLINE explicit operator bool() const
		{
			return !!BitArrayIt;
		}

		/** inverse of the "bool" operator */
		FORCEINLINE bool operator !() const
		{
			return !(bool)*this;
		}

		FORCEINLINE ItElementType& operator*() const { return Array[GetIndex()]; }
		FORCEINLINE ItElementType* operator->() const { return &Array[GetIndex()]; }
		FORCEINLINE const FRelativeBitReference& GetRelativeBitReference() const { return BitArrayIt; }

	protected:
		ArrayType&     Array;
		BitArrayItType BitArrayIt;
	};

public:

	/** Iterates over all allocated elements in a sparse array. */
	class TIterator : public TBaseIterator<false>
	{
	public:
		TIterator(TSparseArray& InArray)
			: TBaseIterator<false>(InArray, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(InArray.AllocationFlags))
		{
		}

		TIterator(TSparseArray& InArray, const typename TBaseIterator<false>::BitArrayItType& InBitArrayIt)
			: TBaseIterator<false>(InArray, InBitArrayIt)
		{
		}

		/** Safely removes the current element from the array. */
		void RemoveCurrent()
		{
			this->Array.RemoveAt(this->GetIndex());
		}
	};

	/** Iterates over all allocated elements in a const sparse array. */
	class TConstIterator : public TBaseIterator<true>
	{
	public:
		TConstIterator(const TSparseArray& InArray)
			: TBaseIterator<true>(InArray, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(InArray.AllocationFlags))
		{
		}

		TConstIterator(const TSparseArray& InArray, const typename TBaseIterator<true>::BitArrayItType& InBitArrayIt)
			: TBaseIterator<true>(InArray, InBitArrayIt)
		{
		}
	};

	#if TSPARSEARRAY_RANGED_FOR_CHECKS
		class TRangedForIterator : public TIterator
		{
		public:
			TRangedForIterator(TSparseArray& InArray, const typename TBaseIterator<false>::BitArrayItType& InBitArrayIt)
				: TIterator (InArray, InBitArrayIt)
				, InitialNum(InArray.Num())
			{
			}

		private:
			int32 InitialNum;

			friend FORCEINLINE bool operator!=(const TRangedForIterator& Lhs, const TRangedForIterator& Rhs)
			{
				// We only need to do the check in this operator, because no other operator will be
				// called until after this one returns.
				//
				// Also, we should only need to check one side of this comparison - if the other iterator isn't
				// even from the same array then the compiler has generated bad code.
				ensureMsgf(Lhs.Array.Num() == Lhs.InitialNum, TEXT("Container has changed during ranged-for iteration!"));
				return *(TIterator*)&Lhs != *(TIterator*)&Rhs;
			}
		};

		class TRangedForConstIterator : public TConstIterator
		{
		public:
			TRangedForConstIterator(const TSparseArray& InArray, const typename TBaseIterator<true>::BitArrayItType& InBitArrayIt)
				: TConstIterator(InArray, InBitArrayIt)
				, InitialNum    (InArray.Num())
			{
			}

		private:
			int32 InitialNum;

			friend FORCEINLINE bool operator!=(const TRangedForConstIterator& Lhs, const TRangedForConstIterator& Rhs)
			{
				// We only need to do the check in this operator, because no other operator will be
				// called until after this one returns.
				//
				// Also, we should only need to check one side of this comparison - if the other iterator isn't
				// even from the same array then the compiler has generated bad code.
				ensureMsgf(Lhs.Array.Num() == Lhs.InitialNum, TEXT("Container has changed during ranged-for iteration!"));
				return *(TIterator*)&Lhs != *(TIterator*)&Rhs;
			}
		};
	#else
		using TRangedForIterator      = TIterator;
		using TRangedForConstIterator = TConstIterator;
	#endif

	/** Creates an iterator for the contents of this array */
	TIterator CreateIterator()
	{
		return TIterator(*this);
	}

	/** Creates a const iterator for the contents of this array */
	TConstIterator CreateConstIterator() const
	{
		return TConstIterator(*this);
	}

private:
	/**
	 * DO NOT USE DIRECTLY
	 * STL-like iterators to enable range-based for loop support.
	 */
	FORCEINLINE friend TRangedForIterator      begin(      TSparseArray& Array) { return TRangedForIterator     (Array, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(Array.AllocationFlags)); }
	FORCEINLINE friend TRangedForConstIterator begin(const TSparseArray& Array) { return TRangedForConstIterator(Array, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(Array.AllocationFlags)); }
	FORCEINLINE friend TRangedForIterator      end  (      TSparseArray& Array) { return TRangedForIterator     (Array, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(Array.AllocationFlags, Array.AllocationFlags.Num())); }
	FORCEINLINE friend TRangedForConstIterator end  (const TSparseArray& Array) { return TRangedForConstIterator(Array, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(Array.AllocationFlags, Array.AllocationFlags.Num())); }

public:
	/** An iterator which only iterates over the elements of the array which correspond to set bits in a separate bit array. */
	template<typename SubsetAllocator = FDefaultBitArrayAllocator>
	class TConstSubsetIterator
	{
	public:
		TConstSubsetIterator( const TSparseArray& InArray, const TBitArray<SubsetAllocator>& InBitArray ):
			Array(InArray),
			BitArrayIt(InArray.AllocationFlags,InBitArray)
		{}
		FORCEINLINE TConstSubsetIterator& operator++()
		{
			// Iterate to the next element which is both allocated and has its bit set in the other bit array.
			++BitArrayIt;
			return *this;
		}
		FORCEINLINE int32 GetIndex() const { return BitArrayIt.GetIndex(); }

		/** conversion to "bool" returning true if the iterator is valid. */
		FORCEINLINE explicit operator bool() const
		{
			return !!BitArrayIt;
		}
		/** inverse of the "bool" operator */
		FORCEINLINE bool operator !() const
		{
			return !(bool)*this;
		}

		FORCEINLINE const ElementType& operator*() const { return Array(GetIndex()); }
		FORCEINLINE const ElementType* operator->() const { return &Array(GetIndex()); }
		FORCEINLINE const FRelativeBitReference& GetRelativeBitReference() const { return BitArrayIt; }
	private:
		const TSparseArray& Array;
		TConstDualSetBitIterator<typename Allocator::BitArrayAllocator,SubsetAllocator> BitArrayIt;
	};

	/** Concatenation operators */
	TSparseArray& operator+=( const TSparseArray& OtherArray )
	{
		this->Reserve(this->Num() + OtherArray.Num());
		for ( typename TSparseArray::TConstIterator It(OtherArray); It; ++It )
		{
			this->Add(*It);
		}
		return *this;
	}
	TSparseArray& operator+=( const TArray<ElementType>& OtherArray )
	{
		this->Reserve(this->Num() + OtherArray.Num());
		for ( int32 Idx = 0; Idx < OtherArray.Num(); Idx++ )
		{
			this->Add(OtherArray[Idx]);
		}
		return *this;
	}

private:

	/**
	 * The element type stored is only indirectly related to the element type requested, to avoid instantiating TArray redundantly for
	 * compatible types.
	 */
	typedef TSparseArrayElementOrFreeListLink<
		TAlignedBytes<sizeof(ElementType), alignof(ElementType)>
		> FElementOrFreeListLink;

	/** Extracts the element value from the array's element structure and passes it to the user provided comparison class. */
	template <typename PREDICATE_CLASS>
	class FElementCompareClass
	{
		const PREDICATE_CLASS& Predicate;

	public:
		FElementCompareClass( const PREDICATE_CLASS& InPredicate )
			: Predicate( InPredicate )
		{}

		bool operator()( const FElementOrFreeListLink& A,const FElementOrFreeListLink& B ) const
		{
			return Predicate(*(ElementType*)&A.ElementData,*(ElementType*)&B.ElementData);
		}
	};

	/** Accessor for the element or free list data. */
	FElementOrFreeListLink& GetData(int32 Index)
	{
		return ((FElementOrFreeListLink*)Data.GetData())[Index];
	}

	/** Accessor for the element or free list data. */
	const FElementOrFreeListLink& GetData(int32 Index) const
	{
		return ((FElementOrFreeListLink*)Data.GetData())[Index];
	}

	typedef TArray<FElementOrFreeListLink,typename Allocator::ElementAllocator> DataType;
	DataType Data;

	typedef TBitArray<typename Allocator::BitArrayAllocator> AllocationBitArrayType;
	AllocationBitArrayType AllocationFlags;

	/** The index of an unallocated element in the array that currently contains the head of the linked list of free elements. */
	int32 FirstFreeIndex;

	/** The number of elements in the free list. */
	int32 NumFreeIndices;
};

template<typename ElementType, typename Allocator>
struct TContainerTraits<TSparseArray<ElementType, Allocator> > : public TContainerTraitsBase<TSparseArray<ElementType, Allocator> >
{
	enum { MoveWillEmptyContainer =
		TContainerTraits<typename TSparseArray<ElementType, Allocator>::DataType>::MoveWillEmptyContainer &&
		TContainerTraits<typename TSparseArray<ElementType, Allocator>::AllocationBitArrayType>::MoveWillEmptyContainer };
};

struct FScriptSparseArrayLayout
{
	int32 ElementOffset;
	int32 Alignment;
	int32 Size;
};

// Untyped sparse array type for accessing TSparseArray data, like FScriptArray for TArray.
// Must have the same memory representation as a TSet.
class FScriptSparseArray
{
public:
	static FScriptSparseArrayLayout GetScriptLayout(int32 ElementSize, int32 ElementAlignment)
	{
		FScriptSparseArrayLayout Result;
		Result.ElementOffset = 0;
		Result.Alignment     = FMath::Max(ElementAlignment, (int32)alignof(FFreeListLink));
		Result.Size          = FMath::Max(ElementSize,      (int32)sizeof (FFreeListLink));

		return Result;
	}

	FScriptSparseArray()
		: FirstFreeIndex(-1)
		, NumFreeIndices(0)
	{
	}

	bool IsValidIndex(int32 Index) const
	{
		return AllocationFlags.IsValidIndex(Index) && AllocationFlags[Index];
	}

	int32 Num() const
	{
		return Data.Num() - NumFreeIndices;
	}

	int32 GetMaxIndex() const
	{
		return Data.Num();
	}

	void* GetData(int32 Index, const FScriptSparseArrayLayout& Layout)
	{
		return (uint8*)Data.GetData() + Layout.Size * Index;
	}

	const void* GetData(int32 Index, const FScriptSparseArrayLayout& Layout) const
	{
		return (const uint8*)Data.GetData() + Layout.Size * Index;
	}

	void Empty(int32 Slack, const FScriptSparseArrayLayout& Layout)
	{
		// Free the allocated elements.
		Data.Empty(Slack, Layout.Size);
		FirstFreeIndex = -1;
		NumFreeIndices = 0;
		AllocationFlags.Empty(Slack);
	}

	/**
	 * Adds an uninitialized object to the array.
	 *
	 * @return  The index of the added element.
	 */
	int32 AddUninitialized(const FScriptSparseArrayLayout& Layout)
	{
		int32 Index;
		if (NumFreeIndices)
		{
			// Remove and use the first index from the list of free elements.
			Index = FirstFreeIndex;
			FirstFreeIndex = GetFreeListLink(FirstFreeIndex, Layout)->NextFreeIndex;
			--NumFreeIndices;
			if(NumFreeIndices)
			{
				GetFreeListLink(FirstFreeIndex, Layout)->PrevFreeIndex = -1;
			}
		}
		else
		{
			// Add a new element.
			Index = Data.Add(1, Layout.Size);
			AllocationFlags.Add(false);
		}

		AllocationFlags[Index] = true;

		return Index;
	}

	/** Removes Count elements from the array, starting from Index, without destructing them. */
	void RemoveAtUninitialized(const FScriptSparseArrayLayout& Layout, int32 Index, int32 Count = 1)
	{
		for (; Count; --Count)
		{
			check(AllocationFlags[Index]);

			// Mark the element as free and add it to the free element list.
			if(NumFreeIndices)
			{
				GetFreeListLink(FirstFreeIndex, Layout)->PrevFreeIndex = Index;
			}

			auto* IndexData = GetFreeListLink(Index, Layout);
			IndexData->PrevFreeIndex = -1;
			IndexData->NextFreeIndex = NumFreeIndices > 0 ? FirstFreeIndex : INDEX_NONE;
			FirstFreeIndex = Index;
			++NumFreeIndices;
			AllocationFlags[Index] = false;

			++Index;
		}
	}

private:
	FScriptArray    Data;
	FScriptBitArray AllocationFlags;
	int32           FirstFreeIndex;
	int32           NumFreeIndices;

	// This function isn't intended to be called, just to be compiled to validate the correctness of the type.
	static void CheckConstraints()
	{
		typedef FScriptSparseArray  ScriptType;
		typedef TSparseArray<int32> RealType;

		// Check that the class footprint is the same
		static_assert(sizeof (ScriptType) == sizeof (RealType), "FScriptSparseArray's size doesn't match TSparseArray");
		static_assert(alignof(ScriptType) == alignof(RealType), "FScriptSparseArray's alignment doesn't match TSparseArray");

		// Check member sizes
		static_assert(sizeof(DeclVal<ScriptType>().Data)            == sizeof(DeclVal<RealType>().Data),            "FScriptSparseArray's Data member size does not match TSparseArray's");
		static_assert(sizeof(DeclVal<ScriptType>().AllocationFlags) == sizeof(DeclVal<RealType>().AllocationFlags), "FScriptSparseArray's AllocationFlags member size does not match TSparseArray's");
		static_assert(sizeof(DeclVal<ScriptType>().FirstFreeIndex)  == sizeof(DeclVal<RealType>().FirstFreeIndex),  "FScriptSparseArray's FirstFreeIndex member size does not match TSparseArray's");
		static_assert(sizeof(DeclVal<ScriptType>().NumFreeIndices)  == sizeof(DeclVal<RealType>().NumFreeIndices),  "FScriptSparseArray's NumFreeIndices member size does not match TSparseArray's");

		// Check member offsets
		static_assert(STRUCT_OFFSET(ScriptType, Data)            == STRUCT_OFFSET(RealType, Data),            "FScriptSparseArray's Data member offset does not match TSparseArray's");
		static_assert(STRUCT_OFFSET(ScriptType, AllocationFlags) == STRUCT_OFFSET(RealType, AllocationFlags), "FScriptSparseArray's AllocationFlags member offset does not match TSparseArray's");
		static_assert(STRUCT_OFFSET(ScriptType, FirstFreeIndex)  == STRUCT_OFFSET(RealType, FirstFreeIndex),  "FScriptSparseArray's FirstFreeIndex member offset does not match TSparseArray's");
		static_assert(STRUCT_OFFSET(ScriptType, NumFreeIndices)  == STRUCT_OFFSET(RealType, NumFreeIndices),  "FScriptSparseArray's NumFreeIndices member offset does not match TSparseArray's");

		// Check free index offsets
		static_assert(STRUCT_OFFSET(ScriptType::FFreeListLink, PrevFreeIndex) == STRUCT_OFFSET(RealType::FElementOrFreeListLink, PrevFreeIndex), "FScriptSparseArray's FFreeListLink's PrevFreeIndex member offset does not match TSparseArray's");
		static_assert(STRUCT_OFFSET(ScriptType::FFreeListLink, NextFreeIndex) == STRUCT_OFFSET(RealType::FElementOrFreeListLink, NextFreeIndex), "FScriptSparseArray's FFreeListLink's NextFreeIndex member offset does not match TSparseArray's");
	}

	struct FFreeListLink
	{
		/** If the element isn't allocated, this is a link to the previous element in the array's free list. */
		int32 PrevFreeIndex;

		/** If the element isn't allocated, this is a link to the next element in the array's free list. */
		int32 NextFreeIndex;
	};

	/** Accessor for the element or free list data. */
	FORCEINLINE FFreeListLink* GetFreeListLink(int32 Index, const FScriptSparseArrayLayout& Layout)
	{
		return (FFreeListLink*)GetData(Index, Layout);
	}

public:
	// These should really be private, because they shouldn't be called, but there's a bunch of code
	// that needs to be fixed first.
	FScriptSparseArray(const FScriptSparseArray&) { check(false); }
	void operator=(const FScriptSparseArray&) { check(false); }
};

template <>
struct TIsZeroConstructType<FScriptSparseArray>
{
	enum { Value = true };
};

/**
 * A placement new operator which constructs an element in a sparse array allocation.
 */
inline void* operator new(size_t Size,const FSparseArrayAllocationInfo& Allocation)
{
	ASSUME(Allocation.Pointer);
	return Allocation.Pointer;
}


text:
@interface LITSettingsViewController () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) IBOutlet UITableView *tableView;

@end

@implementation LITSettingsViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Settings", @"");
        self.tabBarItem.image = [UIImage imageNamed:@"settings.png"];
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)viewWillAppear:(BOOL)animated {
    [self.tableView reloadData];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 2;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if (section == 0)
        return @"Users";
    return @"";
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == 1)
        return 1;
    return 1 + [LITPersonManager sharedInstance].persons.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }

    if (indexPath.section == 1) {
        cell.textLabel.text = @"About";
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    } else  {
        if (indexPath.row != 0) {
            LITPerson *person = (LITPerson *)[[LITPersonManager sharedInstance].persons objectAtIndex:(indexPath.row - 1)];
            cell.textLabel.text = person.name;
            if ([person.name isEqualToString:[LITPersonManager sharedInstance].currentPerson.name]) {
                cell.imageView.image = [UIImage imageNamed:@"checkmark.png"];
            } else {
                cell.imageView.image = nil;
            }
            cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
        } else {
            cell.textLabel.text = @"Add user";
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    if (indexPath.section == 1) {
        LITAboutViewController *aboutVC = [[LITAboutViewController alloc] initWithNibName:@"LITAboutViewController" bundle:nil];
        [self.navigationController pushViewController:aboutVC animated:YES];
    } else if (indexPath.section == 0) {
        if (indexPath.row == 0) {
            LITEditPersonViewController *addPersonVC = [[LITEditPersonViewController alloc] initWithNibName:@"LITEditPersonViewController" bundle:nil];
            [self.navigationController pushViewController:addPersonVC animated:YES];
        } else {
            [[LITPersonManager sharedInstance] selectPersonAtIndex:(indexPath.row - 1)];
            [self.tableView reloadData];
        }
    }
}

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        if (indexPath.row != 0) {
            LITEditPersonViewController *addPersonVC = [[LITEditPersonViewController alloc] initWithNibName:@"LITEditPersonViewController" bundle:nil];
            addPersonVC.inPerson = [[LITPersonManager sharedInstance].persons objectAtIndex:(indexPath.row - 1)];
            [self.navigationController pushViewController:addPersonVC animated:YES];
        }
    }
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [[LITPersonManager sharedInstance] deletePersonAtIndex:indexPath.row];
        [self.tableView reloadData];
    }
}

@end

redpajama_set_name: RedPajamaGithub


text:
package com.gotometrics.orderly;

import java.io.IOException;

import org.apache.hadoop.hbase.io.ImmutableBytesWritable;

/** Serialize and deserialize a struct (record) row key into a sortable
 * byte array.
 *
 *
A struct row key is a composed of a fixed number of fields.
 * Each field is a subclass of {@link RowKey} (and may even be another struct).
 * The struct is sorted by its field values in the order in which the fields
 * are declared.

 *
 *
Structs allow for composite row keys. This is similar to a multi-column
 * primary key or index in MySQL, where the primary key is a struct and the
 * columns are field row keys.

 *
 *
 Serialization Format

 * The struct row key does not serialize any additional bytes beyond those
 * used to serialize each of its fields in sequential order. The struct
 * serializes an array of values by simply serializing the first value using
 * the first row key, followed by the second value serialized with the second
 * row key, and so forth. No bytes are serialized directly by the struct class
 * at all, so no additional bytes are inserted before, after, or in between
 * values serialized by the field row keys. In all cases except the implicit
 * termination cases mentioned below, field row keys have {@link #mustTerminate}
 * set to true to force each field row key to be self-terminating.
 *
 *
 Implicit and Explicit Termination

 * The struct row key does not directly serialize any bytes and thus
 * termination flags do not directly affect the serialization. Instead,
 * the struct row controls explicit and implicit termination settings by
 * manipulating the must terminate flags of the field row keys using
 * {@link #setMustTerminate}.
 *
 *
If mustTerminate is true, then the mustTerminate flag is set
 * to true in all field row keys. However, if mustTerminate
 * is false, we can set the must terminate flag to false for any field row key
 * that is followed by an uninterrupted trailing suffix of ascending-sorted
 * NULL values. This is because NULL values encoded via ascending sort
 * are zero-length in all row key formats (assuming mustTerminate
 * is false). In the extreme, a struct with must terminate set to false and all
 * fields in ascending sort order would serialize a set of null objects to a
 * zero-byte array. All other field row keys (those that are followed by any
 * serialized value with non-zero length) will have the must terminate flag set
 * to true in the field row key.

 *
 *
 Struct Prefixes

 * Given a serialized struct row key, you may deserialize fields from the
 * serialized byte representation using any prefix of the struct row
 * key. For example, if a struct consisting of a long, string, and float
 * is serialized, then fields may be deserialized using a row key consisting of
 * a long and string, or by using a row key consisting of a single
 * long. Any trailing fields omitted from the prefix row key will be ignored
 * during deserialization. In the above example, the (long, string) row key
 * would return a two-element (long object, string object) deserialized result,
 * ignoring the trailing serialized float as this was not included in the
 * struct prefix's definition.
 *
 *
 NULL

 * Structs themselves may not be NULL. However, struct fields may be NULL
 * (so long as the underlying field row key supports NULL), so you can create a
 * struct where every field is NULL.
 *
 *
 Descending sort

 * To sort in descending order we invert the sort order of each field row key.
 *
 *
 Usage

 * Structs impose no extra space during serialization, or object copy overhead
 * at runtime. The storage and runtime costs of a struct row key are the
 * sum of the costs of each of its field row keys.
 *
 * @see StructIterator
 * @see StructBuilder
 */
public class StructRowKey extends RowKey implements Iterable<Object>
{
  private RowKey[] fields;
  private Object[] v;
  private StructIterator iterator;
  private ImmutableBytesWritable iw;

  /** Creates a struct row key object.
   * @param fields - the field row keys of the struct (in declaration order)
   */
  public StructRowKey(RowKey[] fields) { setFields(fields); }

  @Override
  public RowKey setOrder(Order order) {
    if (order == getOrder())
      return this;

    super.setOrder(order);
    for (RowKey field : fields)
      field.setOrder(field.getOrder() == Order.ASCENDING ? Order.DESCENDING :
          Order.ASCENDING);
    return this;
  }

  /** Sets the field row keys.
   * @param fields the fields of the struct (in declaration order)
   * @return this object
   */
  public StructRowKey setFields(RowKey[] fields) {
    this.fields = fields;
    return this;
  }

  /** Gets the field row keys. */
  public RowKey[] getFields() { return fields; }

  @Override
  public Class<?> getSerializedClass() { return Object[].class; }

  private Object[] toValues(Object obj) {
    Object[] o = (Object[]) obj;
    if (o.length != fields.length)
      throw new IndexOutOfBoundsException("Expected " + fields.length
         + " values but got " + o.length + " values");
    return o;
  }

  /** Initializes mustTerminate in each field row key for the
   * specified field values. As a side effect of this computation, the
   * serialized length of the object is computed.
   * @param o field values
   * @return the serialized length of the field values
   */
  private int setTerminateAndGetLength(Object[] o) throws IOException {
    int len = 0;
    boolean fieldTerm = mustTerminate;

    /* We must terminate a field f if (i) mustTerminate is true for this
     * struct or (ii) any field after f has a non-zero deserialized length
     */
    for (int i = o.length - 1; i >= 0; i--) {
      fields[i].setMustTerminate(fieldTerm);
      int objLen = fields[i].getSerializedLength(o[i]);
      if (objLen > 0) {
        fieldTerm = true;
        len += objLen;
      }
    }

    return len;
  }

  @Override
  public int getSerializedLength(Object obj) throws IOException {
    return setTerminateAndGetLength(toValues(obj));
  }

  @Override
  public void serialize(Object obj, ImmutableBytesWritable w)
    throws IOException
  {
    Object[] o = toValues(obj);
    setTerminateAndGetLength(o);
    for (int i = 0; i < o.length; i++)
      fields[i].serialize(o[i], w);
  }

  @Override
  public void skip(ImmutableBytesWritable w) throws IOException {
    for (int i = 0; i < fields.length; i++)
      fields[i].skip(w);
  }

  @Override
  public Object deserialize(ImmutableBytesWritable w) throws IOException {
    if (v == null)
      v = new Object[fields.length];
    for (int i = 0; i < fields.length; i++)
      v[i] = fields[i].deserialize(w);
    return v;
  }

  /** Sets the serialized row key to iterate over. Subsequent calls to
   * {@link #iterator} will iterate over this row key.
   * @param iw serialized row key bytes to use for iteration
   * @return this object
   * @see #iterator
   */

  public StructRowKey iterateOver(ImmutableBytesWritable iw) {
    this.iw = iw;
    return this;
  }

  public StructRowKey iterateOver(byte[] b, int offset) {
    if (iw == null)
      iw = new ImmutableBytesWritable();
    iw.set(b, offset, b.length - offset);
    return this;
  }

  public StructRowKey iterateOver(byte[] b) { return iterateOver(b, 0); }

  /** Iterates over a serialized row key. Re-uses the same iterator object
   * across method calls.
   * @see StructIterator
   * @see #iterateOver
   * @return an iterator for w
   */
  @Override
  public StructIterator iterator() {
    if (iterator == null)
      iterator = new StructIterator(this);
    iterator.reset();
    iterator.setBytes(iw);
    return iterator;
  }
}


text:
'use strict';

var gulp = require('gulp');

// load tasks from ./gulp/tasks/*.js
[
  'browser-sync',
  'nodemon',
  'csslint',
  'jshint',
  'sass',
  'copy-static-assets',
  'build-client',
  'build-css',
  'test'

].forEach(function (name) {
    require('./gulp/tasks/' + name);
  });

// Composite tasks

gulp.task('lint', ['jshint', 'csslint']);
gulp.task('lint:watch', ['jshint:watch', 'csslint:watch']);

gulp.task('build', ['lint', 'sass', 'copy-static-assets', 'build-client', 'build-css']);
gulp.task('build:watch', ['lint:watch', 'sass:watch', 'copy-static-assets:watch', 'build-client:watch', 'build-css:watch']);
gulp.task('build:production', ['build-client:production']);

gulp.task('tdd', ['lint:watch', 'test:watch']);
gulp.task('default', ['build', 'build:watch', 'nodemon', 'browser-sync']);


text:
export const routeActiveConfig: RouteActiveConfig = {
	activeClass: "active",
	attribute: "href",
	matchExact: true
};

export interface RouteActiveConfig {
	activeClass: string;
	attribute: string;
	matchExact: boolean;
}


text:
use super::*;

/// Extensions to the `ParseStream` API to support speculative parsing.
pub trait Speculative {
    /// Advance this parse stream to the position of a forked parse stream.
    ///
    /// This is the opposite operation to [`ParseStream::fork`]. You can fork a
    /// parse stream, perform some speculative parsing, then join the original
    /// stream to the fork to "commit" the parsing from the fork to the main
    /// stream.
    ///
    /// If you can avoid doing this, you should, as it limits the ability to
    /// generate useful errors. That said, it is often the only way to parse
    /// syntax of the form `A* B*` for arbitrary syntax `A` and `B`. The problem
    /// is that when the fork fails to parse an `A`, it's impossible to tell
    /// whether that was because of a syntax error and the user meant to provide
    /// an `A`, or that the `A`s are finished and it's time to start parsing
    /// `B`s. Use with care.
    ///
    /// Also note that if `A` is a subset of `B`, `A* B*` can be parsed by
    /// parsing `B*` and removing the leading members of `A` from the
    /// repetition, bypassing the need to involve the downsides associated with
    /// speculative parsing.
    ///
    /// [`ParseStream::fork`]: ParseBuffer::fork
    ///
    /// # Example
    ///
    /// There has been chatter about the possibility of making the colons in the
    /// turbofish syntax like `path::to::<T>` no longer required by accepting
    /// `path::to<T>` in expression position. Specifically, according to [RFC
    /// 2544], [`PathSegment`] parsing should always try to consume a following
    /// `<` token as the start of generic arguments, and reset to the `<` if
    /// that fails (e.g. the token is acting as a less-than operator).
    ///
    /// This is the exact kind of parsing behavior which requires the "fork,
    /// try, commit" behavior that [`ParseStream::fork`] discourages. With
    /// `advance_to`, we can avoid having to parse the speculatively parsed
    /// content a second time.
    ///
    /// This change in behavior can be implemented in syn by replacing just the
    /// `Parse` implementation for `PathSegment`:
    ///
    /// ```
    /// # use syn::ext::IdentExt;
    /// use syn::parse::discouraged::Speculative;
    /// # use syn::parse::{Parse, ParseStream};
    /// # use syn::{Ident, PathArguments, Result, Token};
    ///
    /// pub struct PathSegment {
    ///     pub ident: Ident,
    ///     pub arguments: PathArguments,
    /// }
    /// #
    /// # impl<T> From<T> for PathSegment
    /// # where
    /// #     T: Into<Ident>,
    /// # {
    /// #     fn from(ident: T) -> Self {
    /// #         PathSegment {
    /// #             ident: ident.into(),
    /// #             arguments: PathArguments::None,
    /// #         }
    /// #     }
    /// # }
    ///
    /// impl Parse for PathSegment {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         if input.peek(Token![super])
    ///             || input.peek(Token![self])
    ///             || input.peek(Token![Self])
    ///             || input.peek(Token![crate])
    ///         {
    ///             let ident = input.call(Ident::parse_any)?;
    ///             return Ok(PathSegment::from(ident));
    ///         }
    ///
    ///         let ident = input.parse()?;
    ///         if input.peek(Token![::]) && input.peek3(Token![<]) {
    ///             return Ok(PathSegment {
    ///                 ident,
    ///                 arguments: PathArguments::AngleBracketed(input.parse()?),
    ///             });
    ///         }
    ///         if input.peek(Token![<]) && !input.peek(Token![<=]) {
    ///             let fork = input.fork();
    ///             if let Ok(arguments) = fork.parse() {
    ///                 input.advance_to(&fork);
    ///                 return Ok(PathSegment {
    ///                     ident,
    ///                     arguments: PathArguments::AngleBracketed(arguments),
    ///                 });
    ///             }
    ///         }
    ///         Ok(PathSegment::from(ident))
    ///     }
    /// }
    ///
    /// # syn::parse_str::<PathSegment>("a<b,c>").unwrap();
    /// ```
    ///
    /// # Drawbacks
    ///
    /// The main drawback of this style of speculative parsing is in error
    /// presentation. Even if the lookahead is the "correct" parse, the error
    /// that is shown is that of the "fallback" parse. To use the same example
    /// as the turbofish above, take the following unfinished "turbofish":
    ///
    /// ```text
    /// let _ = f<&'a fn(), for<'a> serde::>();
    /// ```
    ///
    /// If this is parsed as generic arguments, we can provide the error message
    ///
    /// ```text
    /// error: expected identifier
    ///  --> src.rs:L:C
    ///   |
    /// L | let _ = f<&'a fn(), for<'a> serde::>();
    ///   |                                    ^
    /// ```
    ///
    /// but if parsed using the above speculative parsing, it falls back to
    /// assuming that the `<` is a less-than when it fails to parse the generic
    /// arguments, and tries to interpret the `&'a` as the start of a labelled
    /// loop, resulting in the much less helpful error
    ///
    /// ```text
    /// error: expected `:`
    ///  --> src.rs:L:C
    ///   |
    /// L | let _ = f<&'a fn(), for<'a> serde::>();
    ///   |               ^^
    /// ```
    ///
    /// This can be mitigated with various heuristics (two examples: show both
    /// forks' parse errors, or show the one that consumed more tokens), but
    /// when you can control the grammar, sticking to something that can be
    /// parsed LL(3) and without the LL(*) speculative parsing this makes
    /// possible, displaying reasonable errors becomes much more simple.
    ///
    /// [RFC 2544]: https://github.com/rust-lang/rfcs/pull/2544
    /// [`PathSegment`]: crate::PathSegment
    ///
    /// # Performance
    ///
    /// This method performs a cheap fixed amount of work that does not depend
    /// on how far apart the two streams are positioned.
    ///
    /// # Panics
    ///
    /// The forked stream in the argument of `advance_to` must have been
    /// obtained by forking `self`. Attempting to advance to any other stream
    /// will cause a panic.
    fn advance_to(&self, fork: &Self);
}

impl<'a> Speculative for ParseBuffer<'a> {
    fn advance_to(&self, fork: &Self) {
        if !crate::buffer::same_scope(self.cursor(), fork.cursor()) {
            panic!("Fork was not derived from the advancing parse stream");
        }

        let (self_unexp, self_sp) = inner_unexpected(self);
        let (fork_unexp, fork_sp) = inner_unexpected(fork);
        if !Rc::ptr_eq(&self_unexp, &fork_unexp) {
            match (fork_sp, self_sp) {
                // Unexpected set on the fork, but not on `self`, copy it over.
                (Some(span), None) => {
                    self_unexp.set(Unexpected::Some(span));
                }
                // Unexpected unset. Use chain to propagate errors from fork.
                (None, None) => {
                    fork_unexp.set(Unexpected::Chain(self_unexp));

                    // Ensure toplevel 'unexpected' tokens from the fork don't
                    // bubble up the chain by replacing the root `unexpected`
                    // pointer, only 'unexpected' tokens from existing group
                    // parsers should bubble.
                    fork.unexpected
                        .set(Some(Rc::new(Cell::new(Unexpected::None))));
                }
                // Unexpected has been set on `self`. No changes needed.
                (_, Some(_)) => {}
            }
        }

        // See comment on `cell` in the struct definition.
        self.cell
            .set(unsafe { mem::transmute::<Cursor, Cursor<'static>>(fork.cursor()) });
    }
}


text:
namespace Microsoft.Azure.Batch.Protocol.Models
{
    using Microsoft.Rest;
    using Newtonsoft.Json;
    using System.Linq;

    /// <summary>
    /// Usage metrics for a pool across an aggregation interval.
    /// </summary>
    public partial class PoolUsageMetrics
    {
        /// <summary>
        /// Initializes a new instance of the PoolUsageMetrics class.
        /// </summary>
        public PoolUsageMetrics()
        {
            CustomInit();
        }

        /// <summary>
        /// Initializes a new instance of the PoolUsageMetrics class.
        /// </summary>
        /// <param name="poolId">The ID of the pool whose metrics are
        /// aggregated in this entry.</param>
        /// <param name="startTime">The start time of the aggregation interval
        /// covered by this entry.</param>
        /// <param name="endTime">The end time of the aggregation interval
        /// covered by this entry.</param>
        /// <param name="vmSize">The size of virtual machines in the pool. All
        /// VMs in a pool are the same size.</param>
        /// <param name="totalCoreHours">The total core hours used in the pool
        /// during this aggregation interval.</param>
        /// <param name="dataIngressGiB">The cross data center network ingress
        /// to the pool during this interval, in GiB.</param>
        /// <param name="dataEgressGiB">The cross data center network egress
        /// from the pool during this interval, in GiB.</param>
        public PoolUsageMetrics(string poolId, System.DateTime startTime, System.DateTime endTime, string vmSize, double totalCoreHours, double dataIngressGiB, double dataEgressGiB)
        {
            PoolId = poolId;
            StartTime = startTime;
            EndTime = endTime;
            VmSize = vmSize;
            TotalCoreHours = totalCoreHours;
            DataIngressGiB = dataIngressGiB;
            DataEgressGiB = dataEgressGiB;
            CustomInit();
        }

        /// <summary>
        /// An initialization method that performs custom operations like setting defaults
        /// </summary>
        partial void CustomInit();

        /// <summary>
        /// Gets or sets the ID of the pool whose metrics are aggregated in
        /// this entry.
        /// </summary>
        [JsonProperty(PropertyName = "poolId")]
        public string PoolId { get; set; }

        /// <summary>
        /// Gets or sets the start time of the aggregation interval covered by
        /// this entry.
        /// </summary>
        [JsonProperty(PropertyName = "startTime")]
        public System.DateTime StartTime { get; set; }

        /// <summary>
        /// Gets or sets the end time of the aggregation interval covered by
        /// this entry.
        /// </summary>
        [JsonProperty(PropertyName = "endTime")]
        public System.DateTime EndTime { get; set; }

        /// <summary>
        /// Gets or sets the size of virtual machines in the pool. All VMs in a
        /// pool are the same size.
        /// </summary>
        /// <remarks>
        /// For information about available sizes of virtual machines in pools,
        /// see Choose a VM size for compute nodes in an Azure Batch pool
        /// (https://docs.microsoft.com/azure/batch/batch-pool-vm-sizes). Batch
        /// supports all Cloud Services VM sizes except ExtraSmall,
        /// STANDARD_A1_V2 and STANDARD_A2_V2. For information about available
        /// VM sizes for pools using images from the Virtual Machines
        /// Marketplace (pools created with virtualMachineConfiguration) see
        /// Sizes for Virtual Machines (Linux)
        /// (https://azure.microsoft.com/documentation/articles/virtual-machines-linux-sizes/)
        /// or Sizes for Virtual Machines (Windows)
        /// (https://azure.microsoft.com/documentation/articles/virtual-machines-windows-sizes/).
        /// Batch supports all Azure VM sizes except STANDARD_A0 and those with
        /// premium storage (STANDARD_GS, STANDARD_DS, and STANDARD_DSV2
        /// series).
        /// </remarks>
        [JsonProperty(PropertyName = "vmSize")]
        public string VmSize { get; set; }

        /// <summary>
        /// Gets or sets the total core hours used in the pool during this
        /// aggregation interval.
        /// </summary>
        [JsonProperty(PropertyName = "totalCoreHours")]
        public double TotalCoreHours { get; set; }

        /// <summary>
        /// Gets or sets the cross data center network ingress to the pool
        /// during this interval, in GiB.
        /// </summary>
        [JsonProperty(PropertyName = "dataIngressGiB")]
        public double DataIngressGiB { get; set; }

        /// <summary>
        /// Gets or sets the cross data center network egress from the pool
        /// during this interval, in GiB.
        /// </summary>
        [JsonProperty(PropertyName = "dataEgressGiB")]
        public double DataEgressGiB { get; set; }

        /// <summary>
        /// Validate the object.
        /// </summary>
        /// <exception cref="ValidationException">
        /// Thrown if validation fails
        /// </exception>
        public virtual void Validate()
        {
            if (PoolId == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "PoolId");
            }
            if (VmSize == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "VmSize");
            }
        }
    }
}


text:
using namespace System::Runtime::InteropServices;
using namespace msclr::interop;
using namespace Microsoft::WindowsAPICodePack::DirectX::Utilities;
using namespace Microsoft::WindowsAPICodePack::DirectX::Direct3D10;

EffectConstantBuffer^ Effect::GetConstantBufferByIndex(UInt32 index)
{
    ID3D10EffectConstantBuffer* returnValue = CastInterface<ID3D10Effect>()->GetConstantBufferByIndex(static_cast<UINT>(index));
    return gcnew EffectConstantBuffer(returnValue);
}

EffectConstantBuffer^ Effect::GetConstantBufferByName(String^ name)
{
    IntPtr ptr = Marshal::StringToHGlobalAnsi(name);

    try
    {
        ID3D10EffectConstantBuffer * returnValue = CastInterface<ID3D10Effect>()->GetConstantBufferByName(static_cast<char*>(ptr.ToPointer()));

        return returnValue ? gcnew EffectConstantBuffer(returnValue, false) : nullptr;
    }
    finally
    {
        Marshal::FreeHGlobal(ptr);
    }
}

EffectDescription Effect::Description::get()
{
    EffectDescription desc;
    pin_ptr<EffectDescription> ptr = &desc;

    Validate::VerifyResult(CastInterface<ID3D10Effect>()->GetDesc((D3D10_EFFECT_DESC*)ptr));

    return desc;
}

D3DDevice^ Effect::Device::get(void)
{
    ID3D10Device* tempoutDevice = NULL;
    Validate::VerifyResult(CastInterface<ID3D10Effect>()->GetDevice(&tempoutDevice));

    return tempoutDevice == NULL ? nullptr : gcnew D3DDevice(tempoutDevice);
}

EffectTechnique^ Effect::GetTechniqueByIndex(UInt32 index)
{
    ID3D10EffectTechnique* returnValue = CastInterface<ID3D10Effect>()->GetTechniqueByIndex(static_cast<UINT>(index));
    return gcnew EffectTechnique(returnValue);
}

EffectTechnique^ Effect::GetTechniqueByName(String^ name)
{

    IntPtr ptr = Marshal::StringToHGlobalAnsi(name);

    try
    {
        ID3D10EffectTechnique * returnValue =  CastInterface<ID3D10Effect>()->GetTechniqueByName(static_cast<char*>(ptr.ToPointer()));

        return returnValue ? gcnew EffectTechnique(returnValue, false) : nullptr;
    }
    finally
    {
        Marshal::FreeHGlobal(ptr);
    }
}

EffectVariable^ Effect::GetVariableByIndex(UInt32 index)
{
    return gcnew EffectVariable(CastInterface<ID3D10Effect>()->GetVariableByIndex(static_cast<UINT>(index)), false);
}

EffectVariable^ Effect::GetVariableByName(String^ name)
{
    IntPtr ptr = Marshal::StringToHGlobalAnsi(name);

    try
    {
        ID3D10EffectVariable * returnValue =  CastInterface<ID3D10Effect>()->GetVariableByName(static_cast<char*>(ptr.ToPointer()));
        return returnValue ? gcnew EffectVariable(returnValue, false) : nullptr;
    }
    finally
    {
        Marshal::FreeHGlobal(ptr);
    }
}

EffectVariable^ Effect::GetVariableBySemantic(String^ semantic)
{
    IntPtr ptr = Marshal::StringToHGlobalAnsi(semantic);

    try
    {
        ID3D10EffectVariable * returnValue = CastInterface<ID3D10Effect>()->GetVariableBySemantic(static_cast<char*>(ptr.ToPointer()));

        return returnValue ? gcnew EffectVariable(returnValue, false) : nullptr;
    }
    finally
    {
        Marshal::FreeHGlobal(ptr);
    }
}

Boolean Effect::IsOptimized::get()
{
    return CastInterface<ID3D10Effect>()->IsOptimized() != 0;
}

Boolean Effect::IsPool::get()
{
    return CastInterface<ID3D10Effect>()->IsPool() != 0;
}

Boolean Effect::IsValid::get()
{
    return CastInterface<ID3D10Effect>()->IsValid() != 0;
}

void Effect::Optimize()
{
    Validate::VerifyResult(CastInterface<ID3D10Effect>()->Optimize());
}


text:
#ifndef _cimple_ptr_array_h
#define _cimple_ptr_array_h

#include "config.h"

CIMPLE_NAMESPACE_BEGIN

CIMPLE_CIMPLE_LINKAGE
void append_ptr_array(void**& array, size_t& size, void* ptr);

CIMPLE_NAMESPACE_END

#endif /* _cimple_ptr_array_h */


text:
package com.emc.pie.esa.test;

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;

public class Main {

	public static void main(String[] args) throws URISyntaxException {

		URL resource = Main.class.getResource("test.txt");

		System.out.println(resource.toString());

		File file = new File(resource.toURI());

		System.out.println(file.getAbsoluteFile());

	}

}


text:
package taiga.parser;

import taiga.interfaces.ErrorCode;
import taiga.interfaces.ModelException;
import taiga.interfaces.Node;
import taiga.interfaces.Property;
import taiga.interfaces.TaigaException;
import taiga.parser.node.AArrayBlock;
import taiga.parser.node.AObjectBlock;
import taiga.parser.node.ASelect;
import taiga.parser.node.PBlock;

public class SelectValueParserContext extends TypeScopeParserContext {

	private ASelect select;
	private ParserContext value;
	private ParserContext block;

	protected SelectValueParserContext(ParserContext parent, ASelect select) throws TaigaException {
		super(parent);
		this.select = select;
		value = createValueParserContext(select.getValue());
		PBlock selector = select.getSelector();
		// TODO: provide new implementation classes to support expressions and references as selector values
		if(selector instanceof AArrayBlock) {
			block = new ArrayBlockParserContext(this, (AArrayBlock)selector);
		} else if(selector instanceof AObjectBlock) {
			block = new ObjectBlockParserContext(this, (AObjectBlock) selector, getTypeScope());
		} else {
			logAndThrow(ErrorCode.NOT_SUPPORTED);
		}
	}

	@Override
	public void init() throws TaigaException {
		super.init();
		value.init();
		block.init();
	}

	@Override
	public ValueHolder instantiate(InstanceContext ic) throws TaigaException {
		ValueHolder valueHolder = value.instantiate(ic);
		if(valueHolder == null)
			return null;
		Object value = valueHolder.getValue(Object.class);
		if(value == ValueHolder.ERROR)
			return null;
		ValueHolder blockValue = block.instantiate(ic);
		if(blockValue == null)
			return null;
		Property prop = blockValue.getProperty(Object.class);
		if(prop == null)
			return null;
		if(!(prop instanceof Node)) {
			logAndThrow(ErrorCode.SELECTOR_NOT_OBJECT);
			return null;
		}
		Node node = (Node) prop;
		if(!node.isPropertyValueSet(value))
			return null;
		else {
			try {
				Property p2 = node.getProperty(value);
				return new PropertyValueHolder(p2);
			} catch (ModelException e) {
				logAndThrow(e);
				return null;
			}
		}

	}

	@Override
	protected taiga.parser.node.Node getASTNode() {
		return select;
	}

}


text:
package test;

import java.util.List;

import aQute.bnd.osgi.Builder;
import aQute.bnd.osgi.Processor;
import aQute.bnd.osgi.Verifier;
import junit.framework.TestCase;

public class NativeHeader extends TestCase {
	static Builder b = new Builder();

	static {
		try {

			b.setProperty("Include-Resource",
					"x.so;literal='x',y.so;literal='y',native/libclib_jiio.so;literal='',native/libmlib_jai.so;literal='', org/osgi/test/cases/framework/fragments/tb8/linux_x86/libNative.so;literal=''");
			b.build();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void testFunnyHeader() throws Exception {
		Verifier v = new Verifier(b);
		v.doNative(
				"org/osgi/test/cases/framework/fragments/tb8/linux_x86/libNative.so; osname=Linux; processor=x86; osversion=\"(1000,10000]\",");
		assertBad(v, "name");
	}

	public static void testWildcardNotAtEnd() throws Exception {
		Verifier v = new Verifier(b);
		v.doNative("x.so;osname=win32,*,x.dll");
		assertBad(v, "may only END in wildcard");
	}

	public static void testWildcard() throws Exception {
		Verifier v = new Verifier(b);
		v.doNative("x.so ;y.so;osname=Linux;processor=amd64,*");
		assertOk(v);
	}

	public static void testSimple() throws Exception {
		Verifier v = new Verifier(b);
		v.doNative(
				"\rnative/libclib_jiio.so ;\r" + "native/libmlib_jai.so;\r" + "osname=Linux ;\r" + "processor=amd64\r");
		assertOk(v);
	}

	static void assertOk(Processor v) {
		System.err.println(v.getWarnings());
		System.err.println(v.getErrors());
		assertEquals(0, v.getErrors().size());
		assertEquals(0, v.getWarnings().size());
	}

	static void assertBad(Processor v, String ok) {
		assertEmptyAfterRemove(v.getErrors(), ok);
		assertEmptyAfterRemove(v.getWarnings(), ok);
	}

	private static void assertEmptyAfterRemove(List<String> errors, String ok) {
		for (String s : errors) {
			if (!s.contains(ok))
				fail("Found error/warning that can not be removed: " + s + " : " + ok);
		}
	}

}


text:
<!DOCTYPE html>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">

  <title>I switched to Mac OS</title>

  <meta name="author" content="Shannon Dussoye" />

  <link rel="alternate" type="application/rss+xml" title="Shannon Dussoye - A virtual proof that name is awesome!" href="/feed.xml" />

  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.0/css/font-awesome.min.css" />

      <link rel="stylesheet" href="/css/bootstrap.min.css" />

      <link rel="stylesheet" href="/css/bootstrap-social.css" />

      <link rel="stylesheet" href="/css/main.css" />

      <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic" />

      <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" />

  <meta property="og:title" content="I switched to Mac OS" />

  <meta property="og:description" content="A short story about my exposure to computer and Operating Systems. My first exposure to computing dates back to 2011, when I was gifted an IBM desktop running windows XP for Christmas / finishing primary school / getting into one of the top colleges (at that time) in Mauritius. Computers...">

  <meta property="og:type" content="website" />

  <meta property="og:url" content="http://localhost:4000/2018-07-17-macos-move/" />
  <link rel="canonical" href="http://localhost:4000/2018-07-17-macos-move/" />

  <meta property="og:image" content="http://localhost:4000/img/avatar-icon.png" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:site" content="@shannondussoye" />
  <meta name="twitter:creator" content="@shannondussoye" />

  <meta name="twitter:title" content="I switched to Mac OS" />

  <meta name="twitter:description" content="A short story about my exposure to computer and Operating Systems. My first exposure to computing dates back to 2011, when I was gifted an IBM desktop running windows XP for Christmas / finishing primary school / getting into one of the top colleges (at that time) in Mauritius. Computers...">

  <meta name="twitter:image" content="http://localhost:4000/img/avatar-icon.png" />

      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#main-navbar">
        Toggle navigation

      </button>

        Shannon Dussoye

Home

About Me

Gallery

            Resources

Springboard

D3 Demo

I switched to Mac OS

		  Posted on July 17, 2018

A short story about my exposure to computer and Operating Systems.

My first exposure to computing dates back to 2011, when I was gifted an IBM desktop running windows XP for Christmas / finishing primary school / getting into one of the top colleges (at that time) in Mauritius. Computers were pretty expensive at that time and not everyone was able to afford one, Internet connection was limited and also not allowed due to its cost and I am not sure if there were computing books at the libraries at that time. In a nutshell, I was not like the other kids who started programming at an early age. The main use was playing games and later to support college studies. Long story short - I started using Windows operating system and windows XP was the first one.

Over the time, I learnt how to install OS and transitioned to multiple OSs', mainly Windows Vista (short period), Windows 7 and while doing my degree, I got interested in Linux OS. I started by dual booting Linux Mint and then triple booting with Windows Server 2008 (while learning oracle database). Eventually, I reverted to Windows 7 due to lack of software. While I was moving to Sydney, I bought a Lenovo Ultra book which was running Windows 8. I dual booted Ubuntu but didn't use it most of the time due to lack of drivers - there was a few obstacles running Ubuntu on Lenovo Yoga 2 pro - which I didn't had time to look into and ended up updating to Windows 10.

Fast forward 2016 - Once I completed my course, I wiped off the OS and did a fresh Ubuntu install on the machine. While, I liked using it, there was a few aesthetics that I was not satisfied with and soon came across Elementary OS and started using it which was around mid 2017 and I decided to write a blog about my setup.

Fast forward 2018 - My Lenovo died after 4 years. Contacted support and they thought the motherboard died and need to be replaced. I was advised to get it done through a third-party as i might be a bit cheaper. I knew it was time to get a new laptop and started looking for one. Few considerations:

Dell XPS - Windows :(

Dell XPS Developer Edition -  :O

Lenovo X1 Carbon - Windows :(

Microsoft Surface - Windows +  + small :$

MacBook Pro - am anti apple products (why would I?)

I wanted to get either the XPS/X1 and install Elementary or Ubuntu but remembered the fixes I had to apply to get Linux to work on Windows native Machine. While I was doing my analysis, I came across a MacBook Pro deal which I thought was pretty good and decided to stop looking and bought it (optimal stopping). I have been using the MacBook for a few months now and have not faced any issue with. I am pretty satisfied with it. My work Laptop was also updated to an i7 MacBook pro (touch bar) - which isn't too bad as well but I would not spend the extra  for the touch bar. I haven't found any use of it yet.

I'll be posting the software and tools I installed on the Mac in the next coming weeks. Until then, Stay safe.

          Tags:

            mac

  Share:

      Twitter

      LinkedIn

          ← Previous Post

          Next Post →

              GitHub

              Twitter

              Email me

              LinkedIn

              StackOverflow

		  Shannon Dussoye
		   •
		  2018

		   •
		  ShannonDussoye.com

		  Theme by
		  beautiful-jekyll


text:
using System;
using Shared.Common.Resources;
using TestFramework.Resources;

namespace Shared.TfsIntegration.Resources
{
    public class TfsWriteMock : ITfsWrite
    {
        public int Save(TestRun testrun, int onlyForTestCaseWithId = -1)
        {
            return new Random().Next(100000);
        }

        //public void UpdateTfsWorkItemsAfterNewDeploy(TfsEnvironment environmentToUpdate, string buildNrDeployed)
        //{
        //}
    }
}


text:
using System;
using Moscrif.IDE.Iface.Entities;
using Moscrif.IDE.Option;
using Moscrif.IDE.Iface;
using Moscrif.IDE.Components;
using System.IO;
using MessageDialogs = Moscrif.IDE.Controls.MessageDialog;
using Gtk;

namespace Moscrif.IDE.Controls
{
	public partial class FeedbackDialog : Gtk.Dialog
	{
		Notebook notb = new Notebook();

		FeedbackControl feedbackIssue = new  FeedbackControl(FeedbackControl.TypFeedback.Issue);
		FeedbackControl feedbackQuestion = new  FeedbackControl(FeedbackControl.TypFeedback.Question);
		FeedbackControl feedbackSuggestion = new  FeedbackControl(FeedbackControl.TypFeedback.Suggestion);
		public FeedbackDialog()
		{
			this.TransientFor = MainClass.MainWindow;
			this.Build();

			Pango.FontDescription customFont = lblFeedback.Style.FontDescription.Copy();//  Pango.FontDescription.FromString(MainClass.Settings.ConsoleTaskFont);
			customFont.Size = customFont.Size+(int)(customFont.Size/2);
			customFont.Weight = Pango.Weight.Bold;
			lblFeedback.ModifyFont(customFont);
			lblStatus.ModifyFont(customFont);
			lblStatus.LabelProp = "";

			notb.AppendPage(feedbackIssue,new Label("Report an Issue"));
			notb.AppendPage(feedbackQuestion,new Label("Ask a Question"));
			notb.AppendPage(feedbackSuggestion,new Label("Make a Suggestion"));

			tblMain.Attach(notb,0,2,1,2,AttachOptions.Fill|AttachOptions.Expand,AttachOptions.Fill|AttachOptions.Expand,0,0);
			//imgError.SetFromStock ("gtk-dialog-error", Gtk.IconSize.Dialog);
			tblMain.ShowAll();
		}

		public void LoginYesWrite(object sender, Account  account)
		{

			lblStatus.LabelProp = MainClass.Languages.Translate("feedback-send");
			buttonOk.Sensitive = true;

		}

		public void LoginNoWrite(object sender, string  message)
		{
			lblStatus.LabelProp = MainClass.Languages.Translate("error_feedback");
			buttonOk.Sensitive = true;
			MessageDialogs md =
				new MessageDialogs(MessageDialogs.DialogButtonType.Ok, MainClass.Languages.Translate("error_feedback"),message, Gtk.MessageType.Error,this);
			md.ShowDialog();

		}

		protected void OnButtonOkClicked (object sender, EventArgs e)
		{

			string feedText = "";
			switch (notb.Page){
				case 0:
				feedText = feedbackIssue.GetData();
					break;
				case 1:
				feedText = feedbackQuestion.GetData();
					break;
				case 2:
				feedText = feedbackSuggestion.GetData();
					break;
			}
			Console.WriteLine(feedText);

			if(MainClass.Settings.Account == null)
				Console.WriteLine("Account IS NULL");

			if(String.IsNullOrEmpty(MainClass.Settings.Account.Token))
				Console.WriteLine("Token IS NULL");

			if((MainClass.Settings.Account == null) || (String.IsNullOrEmpty(MainClass.Settings.Account.Token))){
				MessageDialogs md =
					new MessageDialogs(MessageDialogs.DialogButtonType.Ok, MainClass.Languages.Translate("invalid_login_f1"),"", Gtk.MessageType.Error,this);
				md.ShowDialog();
				Console.WriteLine("IS NULL");
				return ;
			}

			buttonOk.Sensitive = false;

			if(string.IsNullOrEmpty(feedText)){
				return;
			}

			lblStatus.LabelProp = "Sending...";
			while (Gtk.Application.EventsPending ())
				Gtk.Application.RunIteration ();

			LoggingInfo log = new LoggingInfo();
			log.SendFeedback (feedText,LoginYesWrite,LoginNoWrite);

			//this.Respond(Gtk.ResponseType.Ok);
		}
	}
}


text:
/*
 * Do not modify this file. This file is generated from the elasticbeanstalk-2010-12-01.normal.json service model.
 */
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Text;
using System.IO;

using Amazon.Runtime;
using Amazon.Runtime.Internal;

namespace Amazon.ElasticBeanstalk.Model
{
    /// <summary>
    /// Represents the average latency for the slowest X percent of requests over the last
    /// 10 seconds.
    /// </summary>
    public partial class Latency
    {
        private double? _p10;
        private double? _p50;
        private double? _p75;
        private double? _p85;
        private double? _p90;
        private double? _p95;
        private double? _p99;
        private double? _p999;

        /// <summary>
        /// Gets and sets the property P10.
        /// <para>
        /// The average latency for the slowest 90 percent of requests over the last 10 seconds.
        /// </para>
        /// </summary>
        public double P10
        {
            get { return this._p10.GetValueOrDefault(); }
            set { this._p10 = value; }
        }

        // Check to see if P10 property is set
        internal bool IsSetP10()
        {
            return this._p10.HasValue;
        }

        /// <summary>
        /// Gets and sets the property P50.
        /// <para>
        /// The average latency for the slowest 50 percent of requests over the last 10 seconds.
        /// </para>
        /// </summary>
        public double P50
        {
            get { return this._p50.GetValueOrDefault(); }
            set { this._p50 = value; }
        }

        // Check to see if P50 property is set
        internal bool IsSetP50()
        {
            return this._p50.HasValue;
        }

        /// <summary>
        /// Gets and sets the property P75.
        /// <para>
        /// The average latency for the slowest 25 percent of requests over the last 10 seconds.
        /// </para>
        /// </summary>
        public double P75
        {
            get { return this._p75.GetValueOrDefault(); }
            set { this._p75 = value; }
        }

        // Check to see if P75 property is set
        internal bool IsSetP75()
        {
            return this._p75.HasValue;
        }

        /// <summary>
        /// Gets and sets the property P85.
        /// <para>
        /// The average latency for the slowest 15 percent of requests over the last 10 seconds.
        /// </para>
        /// </summary>
        public double P85
        {
            get { return this._p85.GetValueOrDefault(); }
            set { this._p85 = value; }
        }

        // Check to see if P85 property is set
        internal bool IsSetP85()
        {
            return this._p85.HasValue;
        }

        /// <summary>
        /// Gets and sets the property P90.
        /// <para>
        /// The average latency for the slowest 10 percent of requests over the last 10 seconds.
        /// </para>
        /// </summary>
        public double P90
        {
            get { return this._p90.GetValueOrDefault(); }
            set { this._p90 = value; }
        }

        // Check to see if P90 property is set
        internal bool IsSetP90()
        {
            return this._p90.HasValue;
        }

        /// <summary>
        /// Gets and sets the property P95.
        /// <para>
        /// The average latency for the slowest 5 percent of requests over the last 10 seconds.
        /// </para>
        /// </summary>
        public double P95
        {
            get { return this._p95.GetValueOrDefault(); }
            set { this._p95 = value; }
        }

        // Check to see if P95 property is set
        internal bool IsSetP95()
        {
            return this._p95.HasValue;
        }

        /// <summary>
        /// Gets and sets the property P99.
        /// <para>
        /// The average latency for the slowest 1 percent of requests over the last 10 seconds.
        /// </para>
        /// </summary>
        public double P99
        {
            get { return this._p99.GetValueOrDefault(); }
            set { this._p99 = value; }
        }

        // Check to see if P99 property is set
        internal bool IsSetP99()
        {
            return this._p99.HasValue;
        }

        /// <summary>
        /// Gets and sets the property P999.
        /// <para>
        /// The average latency for the slowest 0.1 percent of requests over the last 10 seconds.
        /// </para>
        /// </summary>
        public double P999
        {
            get { return this._p999.GetValueOrDefault(); }
            set { this._p999 = value; }
        }

        // Check to see if P999 property is set
        internal bool IsSetP999()
        {
            return this._p999.HasValue;
        }

    }
}


text:
Common interface for different PHP templating engines like Smarty, Twig. This package allows to switch between engines witout changes in your PHP code.

The package was created to be able to migrate to different popular PHP templating engines without need to change my application code. However, it is still needed to modify templates.

### Installation
Using composer: [gelembjuk/templating](http://packagist.org/packages/gelembjuk/templating) ``` require: {"gelembjuk/templating": "1.*"} ```

Additionally, you have to install a template engine you want to use - smarty/smarty or twig/twig (later i hope to add support of other engines).

### Configuration

Configuration is done in run time with a constructor options (as hash argument)

```php
$templateroptions = array(
		'templatepath' => $templatesdir, // directory where templates are stored
		'compiledir' => $compiledir,    // directory to use for compilation temp files. It is needed fro Smarty, but not Twig
		'usecache' => false,       // don't cache . If true then use cache
		'cachedir' => $cachedir,   // path to cache directory. used if `usecache` is true
		'extension' => 'htm' // our templates files will have htm extension
	);
```

### Usage

```php

require '../vendor/autoload.php';

$templater = new Gelembjuk\Templating\SmartyTemplating();
// $templater = new Gelembjuk\Templating\TwigTemplating();

// init template engine
$templater->init($templateroptions);

$templater->setVar('firstname',"John");
$templater->setVar('lastname',"Smith");

$templater->setTemplate('homepage');

// fetch page page content
$pagecontent = $templater->fetchTemplate();

echo $pagecontent;

```
File **homepage.htm** in case of Smarty

```html
<div>

<h1>Hello {$lastname}, {$firstname} </h1>

</div>

```

File **homepage.htm** in case of Twig

```html
<div>

<h1>Hello {{ lastname }}, {{ firstname }} </h1>

</div>

```

### Author

Roman Gelembjuk (@gelembjuk)


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="texmall">
    <meta name="keywords" content="texmall, Texmall, TexMall, tex, mall, TEXMALL">
    <title>Texmall后台管理</title>

    <?php inc_css('bootstrap.min');?>

    <?php inc_css('nifty.min');?>

    <?php inc_css('demo/nifty-demo-icons.min');?>

		            Texmall Admin

404

Page Not Found!

		        Sorry, but the page you are looking for has not been found on our server.

<a class="btn-link" href="<?php echo base_url();?>">返回首页


text:
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class History extends Model
{
    protected $fillable = [
        'user_id',
        'type',
        'text',
    ];

    /**
     * A history belong to an item
     *
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
     */
    public function forItem() {
        return $this->morphTo();
    }
}


text:
"use strict";

const _ = require('lodash');
const tz = require('../lib/TimezoneJS');
const diff = require('deep-diff').diff;

let panicCases = {
"MultiModelImport-10369989": true,
"MultiModelImport-27257231": true,
"MultiModelImport-41139561": true,
"MultiModelImport-57194113": true,
"MultiModelImport-68525351": true,
"MultiModelImport-14769923": true,
"MultiModelImport-29023543": true,
"MultiModelImport-43472779": true,
"MultiModelImport-57624312": true,
"MultiModelImport-70900692": true,
"MultiModelImport-17599671": true,
"MultiModelImport-34692689": true,
"MultiModelImport-4353822": true,
"MultiModelImport-66418197": true,
"MultiModelImport-73275036": true,
"MultiModelImport-18920451": true,
"MultiModelImport-35768267": true,
"MultiModelImport-47499381": true,
"MultiModelImport-66729661": true,
"MultiModelImport-79622373": true,
"MultiModelImport-21958504": true,
"MultiModelImport-36355313": true,
"MultiModelImport-53050154": true,
"MultiModelImport-67005736": true,
"MultiModelImport-95851043": true,
"MultiModelImport-26540427": true,
"MultiModelImport-38149772": true,
"MultiModelImport-55647595": true,
"MultiModelImport-67682249": true,
"MultiModelImport-96947649": true,

"StoryUpdate-91016771": true,
"StoryUpdate-74832161": true,
};

let buggyPlatform = {
'MultiStoryDelete-19984752': true,
'MultiStoryDelete-34466002': true,
'MultiStoryDelete-35566115': true,
'MultiStoryDelete-52798815': true,
'MultiStoryDelete-6094590': true,
'MultiStoryDelete-79245431': true,
'MultiStoryDelete-81709313': true,
'CommentDelete-17742905': true,
'CommentDelete-33343171': true,
'CommentDelete-39883878': true,
'CommentDelete-63196281': true,
'CommentDelete-7855453': true,
'CommentDelete-8839544': true,
'CommentUpdate-451557': true,
'MultiStoryMoveFromProject-68551553': true, // move from doesn't, move *into* moves.  the distinction probably doesn't matter.
'MultiStoryMoveFromProject-92863366': true,
};

let dontgetit = {
'MultiStoryMove-43793222': true, // why does it look like it has an effective velocity of 2 instead of the initial velocity of 1?
};

function projectNow(project) {
  return project.updatedAt;
}

function expectNoDiff(name, one, two) {
  let theDiff = diff(one, two);
  if (theDiff) {
    console.log(`failed: ${name}`);
    console.log(JSON.stringify(theDiff));
    console.log('one', one);
    console.log('two', two);
  }
  expect(theDiff).toEqual(undefined);
}
function expectSuperset(name, superset, subset) {
  let theDiff = diff(superset, subset);
  if (theDiff) {
    // console.log(`diff: ${name}`);
    // console.log(JSON.stringify(theDiff));
  }
  expect(superset).toEqual(jasmine.objectContaining(subset));
}

function activePeople(project) {
  return project.memberships
    .filter(m => m.id)
    .map(m => project.people[m.person_id]);
}

var reducer = require('../dist/bundle').reducer;
var pointScale = require('../dist/bundle').pointScale;
var estimateBugsAndChores = require('../dist/bundle').estimateBugsAndChores;
var iterations = require('../dist/bundle').iterations;
var storyIds = require('../dist/bundle').storyIds;
var stories = require('../dist/bundle').stories;
var shownIterationsStartTime = require('../dist/bundle').shownIterationsStartTime;
var velocity = require('../dist/bundle').velocity;
var panic = require('../dist/bundle').panic;
const fs = require('fs');

function readFixture(key, snapshot) {
  let data = tryRead(key, snapshot + '.json');
  return data && JSON.parse(data);
}

function tryRead(key, fixtureFile) {
  let path = __dirname + '/fixtures/' + key + '/' + fixtureFile;
  try {
    return fs.readFileSync(path, {encoding: 'utf8'});
  } catch(e) {}
}

function iterationsFromSnapshot(snapshot, iterationsSnapshot, now) {
  function convert(timestamp) {
    return new tz.Date(timestamp, snapshot.timezone.olson_name).getTime();
  }
  let iters = iterationsSnapshot.map(iter => ({number: iter.number, start: convert(iter.start), finish: convert(iter.finish), storyIds: iter.story_ids}));
  let numberOfBacklogIterations = iters.filter(iter => iter.finish >= now).length;
  return iters.slice().reverse().slice(0, snapshot.doneIterationsToShow + numberOfBacklogIterations).reverse();
}

function formattedReducedIterations(reduction) {
  let iters = iterations(reduction);
  let numberOfBacklogIterations = iters.filter(iter => iter.type !== 'done').length;
  let formattedIters = iters.map(iter => ({number: iter.number, finish: iter.finish, start: iter.start, storyIds: iter.storyIds}));
  return formattedIters.slice().reverse().slice(0, reduction.doneIterationsToShow + numberOfBacklogIterations).reverse();
}

describe('Project Command Processing', function() {
  fs.readdirSync(__dirname + '/fixtures').slice(0).forEach(function(key) {
    // if (!key.match(/MultiStoryMoveFromProject/)) { return }
    it('creates a patch for ' + key, function() {
      var before  = readFixture(key, 'before');
      var after   = readFixture(key, 'after');
      var afterIterations   = readFixture(key, 'iteration-after');
      var timestamp   = tryRead(key, 'timestamp.txt');
      var command = readFixture(key, 'command').stale_commands[0];
      let beforeState = reducer(undefined, {type: 'RESET_PROJECT', project: before});
      let afterState = reducer(undefined, {type: 'RESET_PROJECT', project: after});

      let now = timestamp ? new Date(timestamp).getTime() : projectNow(afterState);
      beforeState = reducer(beforeState, {type: 'TICK', time: now});
      afterState = reducer(afterState, {type: 'TICK', time: now});

      let reduction = reducer(beforeState, {type: 'RECEIVE_COMMAND', command});

      if (dontgetit[key]) {
        console.log('i dont get it: ' + key);
      } else if (panicCases[key]) {
        expect(panic(reduction)).toEqual(true);
      } else if (buggyPlatform[key]) {
        console.log('buggy platform, check out fixture in ' + key);
      } else {
        expectNoDiff('pointScale', pointScale(reduction), pointScale(afterState));
        expectNoDiff('estimateBugsAndChores', estimateBugsAndChores(reduction), estimateBugsAndChores(afterState));
        expectNoDiff('storyIds', storyIds(reduction), storyIds(afterState));
        expectNoDiff('stories', stories(reduction), stories(afterState));
        expectNoDiff('timezone', reduction.timezone, afterState.timezone);
        expectNoDiff('epicIds', reduction.epicIds, afterState.epicIds);
        expectNoDiff('epics', reduction.epics, afterState.epics);
        expectNoDiff('labels', reduction.labels, afterState.labels);
        expectSuperset('tasks', reduction.tasks, afterState.tasks);
        expectSuperset('comments', reduction.comments, afterState.comments);
        expectSuperset('fileAttachments', reduction.fileAttachments, afterState.fileAttachments);
        expectSuperset('googleAttachments', reduction.googleAttachments, afterState.googleAttachments);
        // expectSuperset('memberships', reduction.memberships, afterState.memberships);
        // expectSuperset('people', reduction.people, afterState.people);
        expectSuperset('active memberships', reduction.memberships.filter(m => m.id), afterState.memberships.filter(m => m.id));
        expectSuperset('active people', activePeople(reduction), activePeople(afterState));
        expectNoDiff('startTime', reduction.startTime, afterState.startTime);
        expectNoDiff('shownIterationsStartTime', shownIterationsStartTime(reduction), shownIterationsStartTime(afterState));
        expectNoDiff('iterationLength', reduction.iterationLength, afterState.iterationLength);
        expectNoDiff('iterationOverrides', reduction.iterationOverrides, afterState.iterationOverrides);
        // console.log(reduction.startTime)
        // console.log(afterState.startTime)
        if (afterIterations) {
          // console.log('reduction.iterationOverrides', reduction.iterationOverrides);
          // console.log('afterState.iterationOverrides', afterState.iterationOverrides);
          // console.log('doneIterations(reduction)', doneIterations(reduction));
          // console.log('iterationsFromSnapshot(afterState, afterIterations)', iterationsFromSnapshot(afterState, afterIterations));
          // console.log('velocity(reduction)', velocity(reduction));
          // // console.log('formattedReducedIterations(reduction)', formattedReducedIterations(reduction));
          // console.log('iterations(reduction)', iterations(reduction));
          // console.log('iterationsFromSnapshot(afterState, afterIterations', iterationsFromSnapshot(afterState, afterIterations));
            // console.log('reduction', reduction);
          expectNoDiff('iterations', formattedReducedIterations(reduction), iterationsFromSnapshot(afterState, afterIterations, now));
        }
      }
    });
  });
});


text:
/**
 * @jsx React.DOM
 */
'use strict';

var assert = require('assert');
var sinon = require('sinon');
var React = require('react');
var HashRouting = require('../HashRouting');
var descriptors = require('../../descriptors');
var Routes = descriptors.Routes;
var Route = descriptors.Route;

function delay(func) {
  setTimeout(func, 10);
}

describe('HashRouting', function() {

  var Main = React.createClass({displayName: 'Main',
    render: function() {
      return React.DOM.div(null, "main");
    }
  });

  var Page = React.createClass({displayName: 'Page',
    render: function() {
      return React.DOM.div(null, "page");
    }
  });

  var routes = (
    Routes(null,
      Route({name: "main", path: "/", view: Main}),
      Route({name: "page", path: "/page", view: Page})
    )
  );

  beforeEach(function() {
    window.location.hash = '';
  });

  it('starts routing', function(done) {
    var onRoute = sinon.spy();
    HashRouting.start(routes, onRoute);
    delay(function() {
      sinon.assert.calledOnce(onRoute);
      assert.equal(onRoute.firstCall.args[0].type.displayName, 'Main');
      assert.deepEqual(onRoute.firstCall.args[2], {initial: true});
      done();
    });
  });

  it('navigates to a different route', function(done) {
    var onRoute = sinon.spy();
    var routing = HashRouting.start(routes, onRoute);
    delay(function() {
      routing.navigate('/page');
      delay(function() {
        sinon.assert.calledTwice(onRoute);
        assert.equal(onRoute.firstCall.args[0].type.displayName, 'Main');
        assert.equal(onRoute.secondCall.args[0].type.displayName, 'Page');
        done();
      });
    });
  });

  it('navigates to a different route with custom navigation params', function(done) {
    var onRoute = sinon.spy();
    var routing = HashRouting.start(routes, onRoute);
    delay(function() {
      routing.navigate('/page', {foo: 'bar'});
      delay(function() {
        sinon.assert.calledTwice(onRoute);
        assert.equal(onRoute.firstCall.args[0].type.displayName, 'Main');
        assert.equal(onRoute.secondCall.args[0].type.displayName, 'Page');
        assert.deepEqual(onRoute.secondCall.args[2], {foo: 'bar'});
        done();
      });
    });
  });

  it('navigates to a different route when query string changes', function(done) {
    var onRoute = sinon.spy();
    var routing = HashRouting.start(routes, onRoute);
    delay(function() {
      routing.navigate('/page');
      routing.navigate('/page?foo=bar');
      delay(function() {
        sinon.assert.calledThrice(onRoute);
        assert.equal(onRoute.firstCall.args[0].type.displayName, 'Main');
        assert.deepEqual(onRoute.firstCall.args[0].props, {query: {}});
        assert.equal(onRoute.secondCall.args[0].type.displayName, 'Page');
        assert.deepEqual(onRoute.secondCall.args[0].props, {query: {}});
        assert.equal(onRoute.thirdCall.args[0].type.displayName, 'Page');
        assert.deepEqual(onRoute.thirdCall.args[0].props, {query: {foo: 'bar'}});
        done();
      });
    });
  });

  it('reacts on hashchange', function(done) {
    var onRoute = sinon.spy();
    var routing = HashRouting.start(routes, onRoute);
    delay(function() {
      routing.navigate('/page');
      delay(function() {
        window.history.back();
        delay(function() {
          sinon.assert.callCount(onRoute, 3);
          assert.equal(onRoute.firstCall.args[0].type.displayName, 'Main');
          assert.equal(onRoute.secondCall.args[0].type.displayName, 'Page');
          assert.equal(onRoute.thirdCall.args[0].type.displayName, 'Main');
          assert.deepEqual(onRoute.thirdCall.args[2], {back: true});
          done();
        });
      });
    });
  });

  it('generates href', function() {
    var onRoute = sinon.spy();
    var routing = HashRouting.start(routes, onRoute);
    assert.equal(routing.makeHref('main'), '#/');
    assert.equal(routing.makeHref('page'), '#/page');
  });

});


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:orientation="vertical">

    <com.uprint.android_pack.cloudprint4androidmanager.widgets.CPIconFontTextView
        android:id="@+id/iconfonttextview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="16dp"
        android:layout_marginTop="6dp" />

    <TextView
        android:id="@+id/nameTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp"
        android:visibility="gone" />

</LinearLayout>