2011-01-18  Ben Vanik  <ben.vanik@gmail.com>

        Reviewed by Kenneth Russell.

        Updating ANGLE in WebKit to r533.
        https://bugs.webkit.org/show_bug.cgi?id=47194

        * platform/graphics/ANGLEWebKitBridge.cpp:
        (WebCore::ANGLEWebKitBridge::ANGLEWebKitBridge):
        (WebCore::ANGLEWebKitBridge::~ANGLEWebKitBridge):
        (WebCore::ANGLEWebKitBridge::validateShaderSource):
        Update to new ANGLE API for shader validation.
        * platform/graphics/ANGLEWebKitBridge.h:
        (WebCore::ANGLEWebKitBridge::setResources): 
        Renaming types to new names.
        * platform/graphics/mac/GraphicsContext3DMac.mm:
        (WebCore::GraphicsContext3D::GraphicsContext3D):
        Initialize ANGLEResources with ANGLE init call to prevent uninitialized variables.
2011-01-18  Ben Vanik  <ben.vanik@gmail.com>

        Reviewed by Kenneth Russell.

        Updating ANGLE in WebKit to r533.
        https://bugs.webkit.org/show_bug.cgi?id=47194

        * ANGLE.xcodeproj/project.pbxproj:
        * include/GLSLANG/ShaderLang.h:
        * src/common/debug.cpp:
        (gl::trace):
        * src/common/debug.h:
        * src/compiler/CodeGenGLSL.cpp:
        (ConstructCompiler):
        * src/compiler/CodeGenHLSL.cpp:
        (ConstructCompiler):
        * src/compiler/Common.h:
        (EncodeSourceLoc):
        (DecodeSourceLoc):
        * src/compiler/Compiler.cpp: Added.
        (TShHandleBase::TShHandleBase):
        (TShHandleBase::~TShHandleBase):
        (TCompiler::TCompiler):
        (TCompiler::~TCompiler):
        (TCompiler::Init):
        (TCompiler::compile):
        (TCompiler::InitBuiltInSymbolTable):
        (TCompiler::clearResults):
        (TCompiler::validateLimitations):
        (TCompiler::collectAttribsUniforms):
        * src/compiler/ExtensionBehavior.h: Added.
        * src/compiler/InfoSink.cpp:
        (TInfoSinkBase::location):
        * src/compiler/InfoSink.h:
        (TInfoSinkBase::size):
        * src/compiler/Initialize.cpp:
        (BuiltInFunctionsCommon):
        (BuiltInFunctionsVertex):
        (BuiltInFunctionsFragment):
        (StandardUniforms):
        (DefaultPrecisionVertex):
        (DefaultPrecisionFragment):
        (BuiltInConstants):
        (TBuiltIns::initialize):
        (IdentifyBuiltIns):
        (InitExtensionBehavior):
        * src/compiler/Initialize.h:
        * src/compiler/IntermTraverse.cpp:
        (TIntermLoop::traverse):
        * src/compiler/Intermediate.cpp:
        (getOperatorString):
        (TIntermediate::addBinaryMath):
        (TIntermediate::addLoop):
        (TIntermediate::postProcess):
        (TIntermBinary::promote):
        * src/compiler/OutputGLSL.cpp:
        (TOutputGLSL::visitUnary):
        (TOutputGLSL::visitLoop):
        * src/compiler/OutputHLSL.cpp:
        (sh::OutputHLSL::OutputHLSL):
        (sh::OutputHLSL::header):
        (sh::OutputHLSL::visitBinary):
        (sh::OutputHLSL::visitUnary):
        (sh::OutputHLSL::visitAggregate):
        (sh::OutputHLSL::visitLoop):
        (sh::OutputHLSL::handleExcessiveLoop):
        (sh::OutputHLSL::argumentString):
        * src/compiler/OutputHLSL.h:
        * src/compiler/ParseHelper.cpp:
        (ReportInfo):
        (DefineExtensionMacros):
        (TParseContext::error):
        (TParseContext::warning):
        (TParseContext::reservedErrorCheck):
        (TParseContext::constructorErrorCheck):
        (TParseContext::arrayQualifierErrorCheck):
        (TParseContext::extensionErrorCheck):
        (TParseContext::areAllChildConst):
        (PaParseStrings):
        * src/compiler/ParseHelper.h:
        (TParseContext::TParseContext):
        * src/compiler/PoolAlloc.cpp:
        (InitializeGlobalPools):
        (FreeGlobalPools):
        (SetGlobalPoolAllocator):
        (TPoolAllocator::TPoolAllocator):
        (TPoolAllocator::~TPoolAllocator):
        (TAllocation::checkAllocList):
        * src/compiler/PoolAlloc.h:
        * src/compiler/SearchSymbol.cpp: Added.
        (sh::SearchSymbol::SearchSymbol):
        (sh::SearchSymbol::traverse):
        (sh::SearchSymbol::visitSymbol):
        (sh::SearchSymbol::foundMatch):
        * src/compiler/SearchSymbol.h: Added.
        * src/compiler/ShHandle.h:
        (TCompiler::getAsCompiler):
        (TCompiler::getInfoSink):
        (TCompiler::getAttribs):
        (TCompiler::getUniforms):
        (TCompiler::getShaderType):
        (TCompiler::getShaderSpec):
        * src/compiler/ShaderLang.cpp:
        (getVariableMaxLength):
        (getVariableInfo):
        (ShInitBuiltInResources):
        (ShConstructCompiler):
        (ShCompile):
        (ShGetInfo):
        (ShGetInfoLog):
        (ShGetObjectCode):
        (ShGetActiveAttrib):
        (ShGetActiveUniform):
        * src/compiler/SymbolTable.cpp:
        (TSymbolTableLevel::relateToExtension):
        * src/compiler/SymbolTable.h:
        (TVariable::shareConstPointer):
        (TFunction::relateToExtension):
        (TFunction::getExtension):
        (TFunction::getParamCount):
        (TFunction::getParam):
        (TSymbolTable::getGlobalLevel):
        (TSymbolTable::relateToOperator):
        (TSymbolTable::relateToExtension):
        * src/compiler/TranslatorGLSL.cpp:
        (writeVersion):
        (TranslatorGLSL::TranslatorGLSL):
        (TranslatorGLSL::translate):
        * src/compiler/TranslatorGLSL.h:
        * src/compiler/TranslatorHLSL.cpp:
        (TranslatorHLSL::TranslatorHLSL):
        (TranslatorHLSL::translate):
        * src/compiler/TranslatorHLSL.h:
        * src/compiler/Types.h:
        (TType::TType):
        * src/compiler/UnfoldSelect.cpp:
        (sh::UnfoldSelect::visitSelection):
        * src/compiler/UnfoldSelect.h:
        * src/compiler/ValidateLimitations.cpp: Added.
        (ValidateLimitations::ValidateLimitations):
        (ValidateLimitations::visitSymbol):
        (ValidateLimitations::visitConstantUnion):
        (ValidateLimitations::visitBinary):
        (ValidateLimitations::visitUnary):
        (ValidateLimitations::visitSelection):
        (ValidateLimitations::visitAggregate):
        (ValidateLimitations::visitLoop):
        (ValidateLimitations::visitBranch):
        (ValidateLimitations::error):
        (ValidateLimitations::withinLoopBody):
        (ValidateLimitations::isLoopIndex):
        (ValidateLimitations::validateLoopType):
        (ValidateLimitations::validateForLoopHeader):
        (ValidateLimitations::validateForLoopInit):
        (ValidateLimitations::validateForLoopCond):
        (ValidateLimitations::validateForLoopExpr):
        (ValidateLimitations::validateFunctionCall):
        (ValidateLimitations::validateOperation):
        (ValidateLimitations::isConstExpr):
        (ValidateLimitations::isConstIndexExpr):
        (ValidateLimitations::validateIndexing):
        * src/compiler/ValidateLimitations.h: Added.
        (ValidateLimitations::numErrors):
        * src/compiler/VariableInfo.cpp: Added.
        (arrayBrackets):
        (getVariableDataType):
        (getVariableInfo):
        (getBuiltInVariableInfo):
        (getUserDefinedVariableInfo):
        (CollectAttribsUniforms::CollectAttribsUniforms):
        (CollectAttribsUniforms::visitSymbol):
        (CollectAttribsUniforms::visitConstantUnion):
        (CollectAttribsUniforms::visitBinary):
        (CollectAttribsUniforms::visitUnary):
        (CollectAttribsUniforms::visitSelection):
        (CollectAttribsUniforms::visitAggregate):
        (CollectAttribsUniforms::visitLoop):
        (CollectAttribsUniforms::visitBranch):
        * src/compiler/VariableInfo.h: Added.
        * src/compiler/VersionGLSL.cpp: Added.
        (TVersionGLSL::TVersionGLSL):
        (TVersionGLSL::visitSymbol):
        (TVersionGLSL::visitConstantUnion):
        (TVersionGLSL::visitBinary):
        (TVersionGLSL::visitUnary):
        (TVersionGLSL::visitSelection):
        (TVersionGLSL::visitAggregate):
        (TVersionGLSL::visitLoop):
        (TVersionGLSL::visitBranch):
        (TVersionGLSL::updateVersion):
        * src/compiler/VersionGLSL.h: Added.
        (TVersionGLSL::getVersion):
        * src/compiler/generate_glslang_lexer.sh: Added.
        * src/compiler/generate_glslang_parser.sh: Added.
        * src/compiler/glslang.h: Added.
        * src/compiler/glslang.l:
        * src/compiler/glslang.y:
        * src/compiler/glslang_lex.cpp: Added.
        (yy_get_next_buffer):
        (yy_get_previous_state):
        (yy_try_NUL_trans):
        (input):
        (yyrestart):
        (yy_switch_to_buffer):
        (yy_load_buffer_state):
        (yy_create_buffer):
        (yy_delete_buffer):
        (yy_init_buffer):
        (yy_flush_buffer):
        (yypush_buffer_state):
        (yypop_buffer_state):
        (yyensure_buffer_stack):
        (yy_scan_buffer):
        (yy_scan_string):
        (yy_scan_bytes):
        (yy_push_state):
        (yy_pop_state):
        (yy_top_state):
        (yy_fatal_error):
        (yyget_extra):
        (yyget_lineno):
        (yyget_column):
        (yyget_in):
        (yyget_out):
        (yyget_leng):
        (yyget_text):
        (yyset_extra):
        (yyset_lineno):
        (yyset_column):
        (yyset_in):
        (yyset_out):
        (yyget_debug):
        (yyset_debug):
        (yyget_lval):
        (yyset_lval):
        (yylex_init):
        (yylex_init_extra):
        (yy_init_globals):
        (yylex_destroy):
        (yy_flex_strncpy):
        (yy_flex_strlen):
        (yyalloc):
        (yyrealloc):
        (yyfree):
        (string_input):
        (check_type):
        (reserved_word):
        (yyerror):
        (glslang_initialize):
        (glslang_finalize):
        (glslang_scan):
        * src/compiler/glslang_tab.cpp: Added.
        (yytnamerr):
        (yysyntax_error):
        (glslang_parse):
        * src/compiler/glslang_tab.h: Added.
        * src/compiler/intermOut.cpp:
        (TOutputTraverser::TOutputTraverser):
        (OutputTreeText):
        (TOutputTraverser::visitSymbol):
        (TOutputTraverser::visitBinary):
        (TOutputTraverser::visitUnary):
        (TOutputTraverser::visitAggregate):
        (TOutputTraverser::visitSelection):
        (TOutputTraverser::visitConstantUnion):
        (TOutputTraverser::visitLoop):
        (TOutputTraverser::visitBranch):
        (TIntermediate::outputTree):
        * src/compiler/intermediate.h:
        (TIntermLoop::TIntermLoop):
        (TIntermLoop::getType):
        (TIntermLoop::getInit):
        (TIntermLoop::getCondition):
        (TIntermLoop::getExpression):
        (TIntermLoop::getBody):
        * src/compiler/localintermediate.h:
        * src/compiler/osinclude.h:
        (OS_GetTLSValue):
        * src/compiler/ossource_nspr.cpp: Added.
        (OS_AllocTLSIndex):
        (OS_SetTLSValue):
        (OS_FreeTLSIndex):
        * src/compiler/preprocessor/compile.h:
        * src/compiler/preprocessor/cpp.c:
        (CPPdefine):
        (CPPelse):
        (CPPif):
        (CPPifdef):
        (CPPerror):
        (CPPextension):
        (readCPPline):
        * src/compiler/preprocessor/preprocess.h:
        * src/compiler/preprocessor/scanner.c:
        (str_getch):
        (str_ungetch):
        (ScanFromString):
        (lFloatConst):
        (byte_scan):
        (yylex_CPP):
        (check_EOF):
        * src/compiler/preprocessor/scanner.h:
        * src/compiler/preprocessor/tokens.c:
        (RecordToken):
        (ReadToken):
        * src/compiler/tools: Removed.
        * src/compiler/unistd.h: Removed.
        * src/compiler/util.cpp: Added.
        (atof_dot):
        * src/compiler/util.h: Added.
        * src/libEGL/Config.cpp:
        (egl::Config::set):
        * src/libEGL/Display.cpp:
        (egl::Display::Display):
        (egl::Display::initialize):
        (egl::Display::terminate):
        (egl::Display::createDevice):
        (egl::Display::resetDevice):
        (egl::Display::createContext):
        (egl::Display::destroyContext):
        (egl::Display::getMinSwapInterval):
        (egl::Display::getMaxSwapInterval):
        (egl::Display::getDevice):
        (egl::Display::getFloatTextureSupport):
        (egl::Display::getHalfFloatTextureSupport):
        (egl::Display::getLuminanceTextureSupport):
        (egl::Display::getLuminanceAlphaTextureSupport):
        (egl::Display::getBufferPool):
        (egl::Display::getEventQuerySupport):
        (egl::Display::getDefaultPresentParameters):
        * src/libEGL/Display.h:
        * src/libEGL/Surface.cpp:
        (egl::Surface::Surface):
        (egl::Surface::~Surface):
        (egl::Surface::release):
        (egl::Surface::resetSwapChain):
        (egl::Surface::writeRecordableFlipState):
        (egl::Surface::restoreState):
        (egl::SurfaceWindowProc):
        (egl::Surface::subclassWindow):
        (egl::Surface::unsubclassWindow):
        (egl::Surface::checkForOutOfDateSwapChain):
        (egl::Surface::convertInterval):
        (egl::Surface::swap):
        (egl::Surface::getRenderTarget):
        (egl::Surface::setSwapInterval):
        * src/libEGL/Surface.h:
        * src/libEGL/libEGL.cpp:
        * src/libGLESv2/Blit.cpp:
        (gl::Blit::copySurfaceToTexture):
        (gl::Blit::setCommonBlitState):
        * src/libGLESv2/Buffer.cpp:
        (gl::Buffer::Buffer):
        (gl::Buffer::~Buffer):
        (gl::Buffer::bufferData):
        (gl::Buffer::bufferSubData):
        (gl::Buffer::getVertexBuffer):
        (gl::Buffer::getIndexBuffer):
        (gl::Buffer::invalidateStaticData):
        * src/libGLESv2/Buffer.h:
        * src/libGLESv2/Context.cpp:
        (gl::Context::Context):
        (gl::Context::~Context):
        (gl::Context::makeCurrent):
        (gl::Context::markAllStateDirty):
        (gl::Context::setFragmentShaderDerivativeHint):
        (gl::Context::setEnableVertexAttribArray):
        (gl::Context::getVertexAttribState):
        (gl::Context::getVertexAttributes):
        (gl::Context::createFence):
        (gl::Context::deleteFence):
        (gl::Context::bindTexture2D):
        (gl::Context::bindTextureCubeMap):
        (gl::Context::getFence):
        (gl::Context::getTexture2D):
        (gl::Context::getTextureCubeMap):
        (gl::Context::getSamplerTexture):
        (gl::Context::getBooleanv):
        (gl::Context::getIntegerv):
        (gl::Context::getQueryParameterInfo):
        (gl::Context::applyRenderTarget):
        (gl::Context::applyState):
        (gl::Context::lookupAttributeMapping):
        (gl::Context::applyVertexBuffer):
        (gl::Context::applyIndexBuffer):
        (gl::Context::readPixels):
        (gl::Context::clear):
        (gl::Context::drawArrays):
        (gl::Context::drawElements):
        (gl::Context::finish):
        (gl::Context::drawClosingLine):
        (gl::Context::getMaximumVaryingVectors):
        (gl::Context::getMaximumFragmentUniformVectors):
        (gl::Context::supportsEventQueries):
        (gl::Context::supportsFloatTextures):
        (gl::Context::supportsFloatLinearFilter):
        (gl::Context::supportsFloatRenderableTextures):
        (gl::Context::supportsHalfFloatTextures):
        (gl::Context::supportsHalfFloatLinearFilter):
        (gl::Context::supportsHalfFloatRenderableTextures):
        (gl::Context::getMaximumRenderbufferDimension):
        (gl::Context::getMaximumTextureDimension):
        (gl::Context::getMaximumCubeTextureDimension):
        (gl::Context::getMaximumTextureLevel):
        (gl::Context::supportsLuminanceTextures):
        (gl::Context::supportsLuminanceAlphaTextures):
        (gl::Context::supports32bitIndices):
        (gl::Context::getIncompleteTexture):
        (gl::Context::setVertexAttrib):
        (gl::Context::initExtensionString):
        (gl::Context::blitFramebuffer):
        * src/libGLESv2/Context.h:
        (gl::VertexAttribute::VertexAttribute):
        (gl::VertexAttribute::typeSize):
        (gl::VertexAttribute::stride):
        * src/libGLESv2/Fence.cpp: Added.
        (gl::Fence::Fence):
        (gl::Fence::~Fence):
        (gl::Fence::isFence):
        (gl::Fence::setFence):
        (gl::Fence::testFence):
        (gl::Fence::finishFence):
        (gl::Fence::getFenceiv):
        * src/libGLESv2/Fence.h: Added.
        * src/libGLESv2/Framebuffer.cpp:
        (gl::Framebuffer::completeness):
        (gl::DefaultFramebuffer::DefaultFramebuffer):
        (gl::DefaultFramebuffer::completeness):
        * src/libGLESv2/Program.cpp:
        (gl::Program::Program):
        (gl::Program::getSamplerMapping):
        (gl::Program::getUniformLocation):
        (gl::Program::setUniform1iv):
        (gl::Program::applyUniforms):
        (gl::Program::packVaryings):
        (gl::Program::linkVaryings):
        (gl::Program::link):
        (gl::Program::defineUniform):
        (gl::Program::createUniform):
        (gl::Program::applyUniform1iv):
        (gl::Program::resetInfoLog):
        (gl::Program::unlink):
        (gl::Program::getActiveAttribute):
        (gl::Program::getActiveUniform):
        (gl::Program::getDxDepthRangeLocation):
        * src/libGLESv2/Program.h:
        * src/libGLESv2/RefCountObject.cpp:
        (gl::RefCountObject::~RefCountObject):
        * src/libGLESv2/Renderbuffer.cpp:
        (gl::RenderbufferStorage::RenderbufferStorage):
        (gl::RenderbufferStorage::isFloatingPoint):
        (gl::Colorbuffer::Colorbuffer):
        (gl::DepthStencilbuffer::DepthStencilbuffer):
        * src/libGLESv2/Renderbuffer.h:
        * src/libGLESv2/Shader.cpp:
        (gl::Shader::Shader):
        (gl::Shader::parseVaryings):
        (gl::Shader::compileToHLSL):
        (gl::VertexShader::parseAttributes):
        * src/libGLESv2/Texture.cpp:
        (gl::Texture::Texture):
        (gl::Texture::isFloatingPoint):
        (gl::Texture::isRenderableFormat):
        (gl::Texture::selectFormat):
        (gl::Texture::loadImageData):
        (gl::Texture::loadAlphaFloatImageData):
        (gl::Texture::loadAlphaHalfFloatImageData):
        (gl::Texture::loadLuminanceImageData):
        (gl::Texture::loadLuminanceFloatImageData):
        (gl::Texture::loadLuminanceHalfFloatImageData):
        (gl::Texture::loadLuminanceAlphaImageData):
        (gl::Texture::loadLuminanceAlphaFloatImageData):
        (gl::Texture::loadLuminanceAlphaHalfFloatImageData):
        (gl::Texture::loadRGBFloatImageData):
        (gl::Texture::loadRGBHalfFloatImageData):
        (gl::Texture::loadRGBAFloatImageData):
        (gl::Texture::loadRGBAHalfFloatImageData):
        (gl::Texture::createSurface):
        (gl::Texture::setImage):
        (gl::Texture::setCompressedImage):
        (gl::Texture::subImage):
        (gl::Texture::subImageCompressed):
        (gl::Texture::copyNonRenderable):
        (gl::Texture::getD3DFormat):
        (gl::Texture::isRenderable):
        (gl::Texture2D::Texture2D):
        (gl::Texture2D::~Texture2D):
        (gl::Texture2D::redefineTexture):
        (gl::Texture2D::setImage):
        (gl::Texture2D::setCompressedImage):
        (gl::Texture2D::copyImage):
        (gl::Texture2D::copySubImage):
        (gl::Texture2D::isComplete):
        (gl::Texture2D::createTexture):
        (gl::Texture2D::convertToRenderTarget):
        (gl::Texture2D::generateMipmaps):
        (gl::Texture2D::getColorbuffer):
        (gl::Texture2D::getRenderTarget):
        (gl::TextureCubeMap::TextureCubeMap):
        (gl::TextureCubeMap::~TextureCubeMap):
        (gl::TextureCubeMap::subImage):
        (gl::TextureCubeMap::subImageCompressed):
        (gl::TextureCubeMap::isComplete):
        (gl::TextureCubeMap::createTexture):
        (gl::TextureCubeMap::convertToRenderTarget):
        (gl::TextureCubeMap::redefineTexture):
        (gl::TextureCubeMap::copyImage):
        (gl::TextureCubeMap::copySubImage):
        (gl::TextureCubeMap::generateMipmaps):
        (gl::TextureCubeMap::getColorbuffer):
        (gl::TextureCubeMap::getRenderTarget):
        (gl::Texture::TextureColorbufferProxy::TextureColorbufferProxy):
        (gl::Texture::TextureColorbufferProxy::isFloatingPoint):
        * src/libGLESv2/Texture.h:
        * src/libGLESv2/geometry/IndexDataManager.cpp:
        (gl::IndexDataManager::IndexDataManager):
        (gl::IndexDataManager::~IndexDataManager):
        (gl::convertIndices):
        (gl::computeRange):
        (gl::IndexDataManager::prepareIndexData):
        (gl::IndexDataManager::indexSize):
        (gl::IndexDataManager::typeSize):
        (gl::IndexBuffer::IndexBuffer):
        (gl::IndexBuffer::~IndexBuffer):
        (gl::IndexBuffer::getBuffer):
        (gl::IndexBuffer::unmap):
        (gl::StreamingIndexBuffer::StreamingIndexBuffer):
        (gl::StreamingIndexBuffer::~StreamingIndexBuffer):
        (gl::StreamingIndexBuffer::map):
        (gl::StreamingIndexBuffer::reserveSpace):
        (gl::StaticIndexBuffer::StaticIndexBuffer):
        (gl::StaticIndexBuffer::~StaticIndexBuffer):
        (gl::StaticIndexBuffer::map):
        (gl::StaticIndexBuffer::reserveSpace):
        (gl::StaticIndexBuffer::lookupType):
        (gl::StaticIndexBuffer::lookupRange):
        (gl::StaticIndexBuffer::addRange):
        * src/libGLESv2/geometry/IndexDataManager.h:
        (gl::IndexBuffer::size):
        * src/libGLESv2/geometry/VertexDataManager.cpp:
        (gl::VertexDataManager::VertexDataManager):
        (gl::VertexDataManager::~VertexDataManager):
        (gl::VertexDataManager::writeAttributeData):
        (gl::VertexDataManager::prepareVertexData):
        (gl::VertexDataManager::spaceRequired):
        (gl::VertexDataManager::checkVertexCaps):
        (gl::VertexDataManager::typeIndex):
        (gl::VertexDataManager::setupAttributes):
        (gl::VertexBuffer::VertexBuffer):
        (gl::VertexBuffer::~VertexBuffer):
        (gl::VertexBuffer::unmap):
        (gl::VertexBuffer::getBuffer):
        (gl::ConstantVertexBuffer::ConstantVertexBuffer):
        (gl::ConstantVertexBuffer::~ConstantVertexBuffer):
        (gl::ArrayVertexBuffer::ArrayVertexBuffer):
        (gl::ArrayVertexBuffer::~ArrayVertexBuffer):
        (gl::ArrayVertexBuffer::addRequiredSpace):
        (gl::ArrayVertexBuffer::addRequiredSpaceFor):
        (gl::StreamingVertexBuffer::StreamingVertexBuffer):
        (gl::StreamingVertexBuffer::~StreamingVertexBuffer):
        (gl::StreamingVertexBuffer::map):
        (gl::StreamingVertexBuffer::reserveRequiredSpace):
        (gl::StaticVertexBuffer::StaticVertexBuffer):
        (gl::StaticVertexBuffer::~StaticVertexBuffer):
        (gl::StaticVertexBuffer::map):
        (gl::StaticVertexBuffer::reserveRequiredSpace):
        (gl::StaticVertexBuffer::lookupAttribute):
        (gl::VertexDataManager::formatConverter):
        * src/libGLESv2/geometry/VertexDataManager.h:
        (gl::ArrayVertexBuffer::size):
        (gl::VertexDataManager::dirtyCurrentValue):
        * src/libGLESv2/geometry/backend.cpp: Removed.
        * src/libGLESv2/geometry/backend.h: Removed.
        * src/libGLESv2/geometry/dx9.cpp: Removed.
        * src/libGLESv2/geometry/dx9.h: Removed.
        * src/libGLESv2/libGLESv2.cpp:
        * src/libGLESv2/libGLESv2.def:
        * src/libGLESv2/libGLESv2.vcproj:
        * src/libGLESv2/utilities.cpp:
        (gl::UniformComponentCount):
        (gl::UniformComponentType):
        (gl::ComputePixelSize):
        (gl::CheckTextureFormatType):
        (gl::IsColorRenderable):
        (gl::IsDepthRenderable):
        (gl::IsStencilRenderable):
        (es2dx::GetAlphaSize):
        (es2dx::GetRedSize):
        (es2dx::GetGreenSize):
        (es2dx::GetBlueSize):
        (es2dx::GetDepthSize):
        (es2dx::ConvertPrimitiveType):
        (dx2es::ConvertBackBufferFormat):
        (dx2es::ConvertDepthStencilFormat):
        * src/libGLESv2/utilities.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76091 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj
index 066a930..6f91926 100644
--- a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj
+++ b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj
@@ -7,6 +7,22 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		90D9B10212E11DCB002D4255 /* Compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B0F912E11DCB002D4255 /* Compiler.cpp */; };
+		90D9B10312E11DCB002D4255 /* ExtensionBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B0FA12E11DCB002D4255 /* ExtensionBehavior.h */; };
+		90D9B10412E11DCB002D4255 /* glslang_lex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B0FB12E11DCB002D4255 /* glslang_lex.cpp */; };
+		90D9B10512E11DCB002D4255 /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B0FC12E11DCB002D4255 /* glslang_tab.cpp */; };
+		90D9B10612E11DCB002D4255 /* glslang_tab.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B0FD12E11DCB002D4255 /* glslang_tab.h */; };
+		90D9B10712E11DCB002D4255 /* glslang.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B0FE12E11DCB002D4255 /* glslang.h */; };
+		90D9B10912E11DCB002D4255 /* SearchSymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B10012E11DCB002D4255 /* SearchSymbol.cpp */; };
+		90D9B10A12E11DCB002D4255 /* SearchSymbol.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B10112E11DCB002D4255 /* SearchSymbol.h */; };
+		90D9B11312E11DD6002D4255 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B10B12E11DD6002D4255 /* util.cpp */; };
+		90D9B11412E11DD6002D4255 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B10C12E11DD6002D4255 /* util.h */; };
+		90D9B11512E11DD6002D4255 /* ValidateLimitations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B10D12E11DD6002D4255 /* ValidateLimitations.cpp */; };
+		90D9B11612E11DD6002D4255 /* ValidateLimitations.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B10E12E11DD6002D4255 /* ValidateLimitations.h */; };
+		90D9B11712E11DD6002D4255 /* VariableInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B10F12E11DD6002D4255 /* VariableInfo.cpp */; };
+		90D9B11812E11DD6002D4255 /* VariableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B11012E11DD6002D4255 /* VariableInfo.h */; };
+		90D9B11912E11DD6002D4255 /* VersionGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B11112E11DD6002D4255 /* VersionGLSL.cpp */; };
+		90D9B11A12E11DD6002D4255 /* VersionGLSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B11212E11DD6002D4255 /* VersionGLSL.h */; };
 		FB39D2711200F35A00088E69 /* CodeGenGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */; };
 		FB39D2751200F35A00088E69 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D2261200F35A00088E69 /* debug.cpp */; };
 		FB39D2791200F35A00088E69 /* InfoSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D22A1200F35A00088E69 /* InfoSink.cpp */; };
@@ -42,6 +58,23 @@
 		5D7C59C51208C68B001C873E /* ANGLE.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ANGLE.xcconfig; sourceTree = "<group>"; };
 		5D7C59C61208C68B001C873E /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
 		5D7C59C71208C68B001C873E /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
+		90D9B0F912E11DCB002D4255 /* Compiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Compiler.cpp; sourceTree = "<group>"; };
+		90D9B0FA12E11DCB002D4255 /* ExtensionBehavior.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtensionBehavior.h; sourceTree = "<group>"; };
+		90D9B0FB12E11DCB002D4255 /* glslang_lex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_lex.cpp; sourceTree = "<group>"; };
+		90D9B0FC12E11DCB002D4255 /* glslang_tab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_tab.cpp; sourceTree = "<group>"; };
+		90D9B0FD12E11DCB002D4255 /* glslang_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glslang_tab.h; sourceTree = "<group>"; };
+		90D9B0FE12E11DCB002D4255 /* glslang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glslang.h; sourceTree = "<group>"; };
+		90D9B0FF12E11DCB002D4255 /* ossource_nspr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossource_nspr.cpp; sourceTree = "<group>"; };
+		90D9B10012E11DCB002D4255 /* SearchSymbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SearchSymbol.cpp; sourceTree = "<group>"; };
+		90D9B10112E11DCB002D4255 /* SearchSymbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchSymbol.h; sourceTree = "<group>"; };
+		90D9B10B12E11DD6002D4255 /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
+		90D9B10C12E11DD6002D4255 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
+		90D9B10D12E11DD6002D4255 /* ValidateLimitations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ValidateLimitations.cpp; sourceTree = "<group>"; };
+		90D9B10E12E11DD6002D4255 /* ValidateLimitations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidateLimitations.h; sourceTree = "<group>"; };
+		90D9B10F12E11DD6002D4255 /* VariableInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableInfo.cpp; sourceTree = "<group>"; };
+		90D9B11012E11DD6002D4255 /* VariableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableInfo.h; sourceTree = "<group>"; };
+		90D9B11112E11DD6002D4255 /* VersionGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VersionGLSL.cpp; sourceTree = "<group>"; };
+		90D9B11212E11DD6002D4255 /* VersionGLSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VersionGLSL.h; sourceTree = "<group>"; };
 		FB39D0D11200F0E300088E69 /* libANGLE.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libANGLE.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		FB39D1861200F26200088E69 /* BaseTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseTypes.h; sourceTree = "<group>"; };
 		FB39D1871200F26200088E69 /* CodeGenGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenGLSL.cpp; sourceTree = "<group>"; };
@@ -112,7 +145,6 @@
 		FB39D1D11200F26200088E69 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = "<group>"; };
 		FB39D1D21200F26200088E69 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; };
 		FB39D1D31200F26200088E69 /* UnfoldSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnfoldSelect.h; sourceTree = "<group>"; };
-		FB39D1D41200F26200088E69 /* unistd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = "<group>"; };
 		FB39D2211200F35A00088E69 /* BaseTypes.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = BaseTypes.h; sourceTree = "<group>"; };
 		FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenGLSL.cpp; sourceTree = "<group>"; };
 		FB39D2241200F35A00088E69 /* Common.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = Common.h; sourceTree = "<group>"; };
@@ -175,7 +207,6 @@
 		FB39D26C1200F35A00088E69 /* Types.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = Types.h; sourceTree = "<group>"; };
 		FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; };
 		FB39D26E1200F35A00088E69 /* UnfoldSelect.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = UnfoldSelect.h; sourceTree = "<group>"; };
-		FB39D26F1200F35A00088E69 /* unistd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = "<group>"; };
 		FB39D2BF1200F3E600088E69 /* ShaderLang.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = ShaderLang.h; sourceTree = "<group>"; };
 		FB39D7201201032000088E69 /* glslang.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = glslang.cpp; path = DerivedSources/ANGLE/glslang.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
 		FB39D7211201032000088E69 /* glslang_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = glslang_tab.h; path = DerivedSources/ANGLE/glslang_tab.h; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -297,7 +328,6 @@
 				FB39D1D11200F26200088E69 /* Types.h */,
 				FB39D1D21200F26200088E69 /* UnfoldSelect.cpp */,
 				FB39D1D31200F26200088E69 /* UnfoldSelect.h */,
-				FB39D1D41200F26200088E69 /* unistd.h */,
 			);
 			includeInIndex = 0;
 			name = compiler;
@@ -332,12 +362,19 @@
 		FB39D2201200F35A00088E69 /* compiler */ = {
 			isa = PBXGroup;
 			children = (
+				FB39D2441200F35A00088E69 /* preprocessor */,
 				FB39D2211200F35A00088E69 /* BaseTypes.h */,
 				FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */,
 				FB39D2241200F35A00088E69 /* Common.h */,
+				90D9B0F912E11DCB002D4255 /* Compiler.cpp */,
 				FB39D2251200F35A00088E69 /* ConstantUnion.h */,
 				FB39D2261200F35A00088E69 /* debug.cpp */,
 				FB39D2271200F35A00088E69 /* debug.h */,
+				90D9B0FA12E11DCB002D4255 /* ExtensionBehavior.h */,
+				90D9B0FB12E11DCB002D4255 /* glslang_lex.cpp */,
+				90D9B0FC12E11DCB002D4255 /* glslang_tab.cpp */,
+				90D9B0FD12E11DCB002D4255 /* glslang_tab.h */,
+				90D9B0FE12E11DCB002D4255 /* glslang.h */,
 				FB39D2281200F35A00088E69 /* glslang.l */,
 				FB39D2291200F35A00088E69 /* glslang.y */,
 				FB39D22A1200F35A00088E69 /* InfoSink.cpp */,
@@ -355,6 +392,7 @@
 				FB39D2361200F35A00088E69 /* localintermediate.h */,
 				FB39D2371200F35A00088E69 /* MMap.h */,
 				FB39D2381200F35A00088E69 /* osinclude.h */,
+				90D9B0FF12E11DCB002D4255 /* ossource_nspr.cpp */,
 				FB39D2391200F35A00088E69 /* ossource_posix.cpp */,
 				FB39D23A1200F35A00088E69 /* ossource_win.cpp */,
 				FB39D23B1200F35A00088E69 /* OutputGLSL.cpp */,
@@ -364,11 +402,12 @@
 				FB39D2411200F35A00088E69 /* ParseHelper.h */,
 				FB39D2421200F35A00088E69 /* PoolAlloc.cpp */,
 				FB39D2431200F35A00088E69 /* PoolAlloc.h */,
-				FB39D2441200F35A00088E69 /* preprocessor */,
 				FB39D2561200F35A00088E69 /* QualifierAlive.cpp */,
 				FB39D2571200F35A00088E69 /* QualifierAlive.h */,
 				FB39D2581200F35A00088E69 /* RemoveTree.cpp */,
 				FB39D2591200F35A00088E69 /* RemoveTree.h */,
+				90D9B10012E11DCB002D4255 /* SearchSymbol.cpp */,
+				90D9B10112E11DCB002D4255 /* SearchSymbol.h */,
 				FB39D25A1200F35A00088E69 /* ShaderLang.cpp */,
 				FB39D25B1200F35A00088E69 /* ShHandle.h */,
 				FB39D25C1200F35A00088E69 /* SymbolTable.cpp */,
@@ -378,7 +417,14 @@
 				FB39D26C1200F35A00088E69 /* Types.h */,
 				FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */,
 				FB39D26E1200F35A00088E69 /* UnfoldSelect.h */,
-				FB39D26F1200F35A00088E69 /* unistd.h */,
+				90D9B10B12E11DD6002D4255 /* util.cpp */,
+				90D9B10C12E11DD6002D4255 /* util.h */,
+				90D9B10D12E11DD6002D4255 /* ValidateLimitations.cpp */,
+				90D9B10E12E11DD6002D4255 /* ValidateLimitations.h */,
+				90D9B10F12E11DD6002D4255 /* VariableInfo.cpp */,
+				90D9B11012E11DD6002D4255 /* VariableInfo.h */,
+				90D9B11112E11DD6002D4255 /* VersionGLSL.cpp */,
+				90D9B11212E11DD6002D4255 /* VersionGLSL.h */,
 			);
 			name = compiler;
 			path = src/compiler;
@@ -425,6 +471,14 @@
 			buildActionMask = 2147483647;
 			files = (
 				FB39D76E120110FC00088E69 /* ShaderLang.h in Headers */,
+				90D9B10312E11DCB002D4255 /* ExtensionBehavior.h in Headers */,
+				90D9B10612E11DCB002D4255 /* glslang_tab.h in Headers */,
+				90D9B10712E11DCB002D4255 /* glslang.h in Headers */,
+				90D9B10A12E11DCB002D4255 /* SearchSymbol.h in Headers */,
+				90D9B11412E11DD6002D4255 /* util.h in Headers */,
+				90D9B11612E11DD6002D4255 /* ValidateLimitations.h in Headers */,
+				90D9B11812E11DD6002D4255 /* VariableInfo.h in Headers */,
+				90D9B11A12E11DD6002D4255 /* VersionGLSL.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -543,6 +597,14 @@
 				FB39D2AA1200F35A00088E69 /* SymbolTable.cpp in Sources */,
 				FB39D2AC1200F35A00088E69 /* TranslatorGLSL.cpp in Sources */,
 				FB39D2B11200F35A00088E69 /* UnfoldSelect.cpp in Sources */,
+				90D9B10212E11DCB002D4255 /* Compiler.cpp in Sources */,
+				90D9B10412E11DCB002D4255 /* glslang_lex.cpp in Sources */,
+				90D9B10512E11DCB002D4255 /* glslang_tab.cpp in Sources */,
+				90D9B10912E11DCB002D4255 /* SearchSymbol.cpp in Sources */,
+				90D9B11312E11DD6002D4255 /* util.cpp in Sources */,
+				90D9B11512E11DD6002D4255 /* ValidateLimitations.cpp in Sources */,
+				90D9B11712E11DD6002D4255 /* VariableInfo.cpp in Sources */,
+				90D9B11912E11DD6002D4255 /* VersionGLSL.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/Source/ThirdParty/ANGLE/ChangeLog b/Source/ThirdParty/ANGLE/ChangeLog
index bd993b7..e7d8e72 100644
--- a/Source/ThirdParty/ANGLE/ChangeLog
+++ b/Source/ThirdParty/ANGLE/ChangeLog
@@ -1,3 +1,598 @@
+2011-01-18  Ben Vanik  <ben.vanik@gmail.com>
+
+        Reviewed by Kenneth Russell.
+
+        Updating ANGLE in WebKit to r533.
+        https://bugs.webkit.org/show_bug.cgi?id=47194
+
+        * ANGLE.xcodeproj/project.pbxproj:
+        * include/GLSLANG/ShaderLang.h:
+        * src/common/debug.cpp:
+        (gl::trace):
+        * src/common/debug.h:
+        * src/compiler/CodeGenGLSL.cpp:
+        (ConstructCompiler):
+        * src/compiler/CodeGenHLSL.cpp:
+        (ConstructCompiler):
+        * src/compiler/Common.h:
+        (EncodeSourceLoc):
+        (DecodeSourceLoc):
+        * src/compiler/Compiler.cpp: Added.
+        (TShHandleBase::TShHandleBase):
+        (TShHandleBase::~TShHandleBase):
+        (TCompiler::TCompiler):
+        (TCompiler::~TCompiler):
+        (TCompiler::Init):
+        (TCompiler::compile):
+        (TCompiler::InitBuiltInSymbolTable):
+        (TCompiler::clearResults):
+        (TCompiler::validateLimitations):
+        (TCompiler::collectAttribsUniforms):
+        * src/compiler/ExtensionBehavior.h: Added.
+        * src/compiler/InfoSink.cpp:
+        (TInfoSinkBase::location):
+        * src/compiler/InfoSink.h:
+        (TInfoSinkBase::size):
+        * src/compiler/Initialize.cpp:
+        (BuiltInFunctionsCommon):
+        (BuiltInFunctionsVertex):
+        (BuiltInFunctionsFragment):
+        (StandardUniforms):
+        (DefaultPrecisionVertex):
+        (DefaultPrecisionFragment):
+        (BuiltInConstants):
+        (TBuiltIns::initialize):
+        (IdentifyBuiltIns):
+        (InitExtensionBehavior):
+        * src/compiler/Initialize.h:
+        * src/compiler/IntermTraverse.cpp:
+        (TIntermLoop::traverse):
+        * src/compiler/Intermediate.cpp:
+        (getOperatorString):
+        (TIntermediate::addBinaryMath):
+        (TIntermediate::addLoop):
+        (TIntermediate::postProcess):
+        (TIntermBinary::promote):
+        * src/compiler/OutputGLSL.cpp:
+        (TOutputGLSL::visitUnary):
+        (TOutputGLSL::visitLoop):
+        * src/compiler/OutputHLSL.cpp:
+        (sh::OutputHLSL::OutputHLSL):
+        (sh::OutputHLSL::header):
+        (sh::OutputHLSL::visitBinary):
+        (sh::OutputHLSL::visitUnary):
+        (sh::OutputHLSL::visitAggregate):
+        (sh::OutputHLSL::visitLoop):
+        (sh::OutputHLSL::handleExcessiveLoop):
+        (sh::OutputHLSL::argumentString):
+        * src/compiler/OutputHLSL.h:
+        * src/compiler/ParseHelper.cpp:
+        (ReportInfo):
+        (DefineExtensionMacros):
+        (TParseContext::error):
+        (TParseContext::warning):
+        (TParseContext::reservedErrorCheck):
+        (TParseContext::constructorErrorCheck):
+        (TParseContext::arrayQualifierErrorCheck):
+        (TParseContext::extensionErrorCheck):
+        (TParseContext::areAllChildConst):
+        (PaParseStrings):
+        * src/compiler/ParseHelper.h:
+        (TParseContext::TParseContext):
+        * src/compiler/PoolAlloc.cpp:
+        (InitializeGlobalPools):
+        (FreeGlobalPools):
+        (SetGlobalPoolAllocator):
+        (TPoolAllocator::TPoolAllocator):
+        (TPoolAllocator::~TPoolAllocator):
+        (TAllocation::checkAllocList):
+        * src/compiler/PoolAlloc.h:
+        * src/compiler/SearchSymbol.cpp: Added.
+        (sh::SearchSymbol::SearchSymbol):
+        (sh::SearchSymbol::traverse):
+        (sh::SearchSymbol::visitSymbol):
+        (sh::SearchSymbol::foundMatch):
+        * src/compiler/SearchSymbol.h: Added.
+        * src/compiler/ShHandle.h:
+        (TCompiler::getAsCompiler):
+        (TCompiler::getInfoSink):
+        (TCompiler::getAttribs):
+        (TCompiler::getUniforms):
+        (TCompiler::getShaderType):
+        (TCompiler::getShaderSpec):
+        * src/compiler/ShaderLang.cpp:
+        (getVariableMaxLength):
+        (getVariableInfo):
+        (ShInitBuiltInResources):
+        (ShConstructCompiler):
+        (ShCompile):
+        (ShGetInfo):
+        (ShGetInfoLog):
+        (ShGetObjectCode):
+        (ShGetActiveAttrib):
+        (ShGetActiveUniform):
+        * src/compiler/SymbolTable.cpp:
+        (TSymbolTableLevel::relateToExtension):
+        * src/compiler/SymbolTable.h:
+        (TVariable::shareConstPointer):
+        (TFunction::relateToExtension):
+        (TFunction::getExtension):
+        (TFunction::getParamCount):
+        (TFunction::getParam):
+        (TSymbolTable::getGlobalLevel):
+        (TSymbolTable::relateToOperator):
+        (TSymbolTable::relateToExtension):
+        * src/compiler/TranslatorGLSL.cpp:
+        (writeVersion):
+        (TranslatorGLSL::TranslatorGLSL):
+        (TranslatorGLSL::translate):
+        * src/compiler/TranslatorGLSL.h:
+        * src/compiler/TranslatorHLSL.cpp:
+        (TranslatorHLSL::TranslatorHLSL):
+        (TranslatorHLSL::translate):
+        * src/compiler/TranslatorHLSL.h:
+        * src/compiler/Types.h:
+        (TType::TType):
+        * src/compiler/UnfoldSelect.cpp:
+        (sh::UnfoldSelect::visitSelection):
+        * src/compiler/UnfoldSelect.h:
+        * src/compiler/ValidateLimitations.cpp: Added.
+        (ValidateLimitations::ValidateLimitations):
+        (ValidateLimitations::visitSymbol):
+        (ValidateLimitations::visitConstantUnion):
+        (ValidateLimitations::visitBinary):
+        (ValidateLimitations::visitUnary):
+        (ValidateLimitations::visitSelection):
+        (ValidateLimitations::visitAggregate):
+        (ValidateLimitations::visitLoop):
+        (ValidateLimitations::visitBranch):
+        (ValidateLimitations::error):
+        (ValidateLimitations::withinLoopBody):
+        (ValidateLimitations::isLoopIndex):
+        (ValidateLimitations::validateLoopType):
+        (ValidateLimitations::validateForLoopHeader):
+        (ValidateLimitations::validateForLoopInit):
+        (ValidateLimitations::validateForLoopCond):
+        (ValidateLimitations::validateForLoopExpr):
+        (ValidateLimitations::validateFunctionCall):
+        (ValidateLimitations::validateOperation):
+        (ValidateLimitations::isConstExpr):
+        (ValidateLimitations::isConstIndexExpr):
+        (ValidateLimitations::validateIndexing):
+        * src/compiler/ValidateLimitations.h: Added.
+        (ValidateLimitations::numErrors):
+        * src/compiler/VariableInfo.cpp: Added.
+        (arrayBrackets):
+        (getVariableDataType):
+        (getVariableInfo):
+        (getBuiltInVariableInfo):
+        (getUserDefinedVariableInfo):
+        (CollectAttribsUniforms::CollectAttribsUniforms):
+        (CollectAttribsUniforms::visitSymbol):
+        (CollectAttribsUniforms::visitConstantUnion):
+        (CollectAttribsUniforms::visitBinary):
+        (CollectAttribsUniforms::visitUnary):
+        (CollectAttribsUniforms::visitSelection):
+        (CollectAttribsUniforms::visitAggregate):
+        (CollectAttribsUniforms::visitLoop):
+        (CollectAttribsUniforms::visitBranch):
+        * src/compiler/VariableInfo.h: Added.
+        * src/compiler/VersionGLSL.cpp: Added.
+        (TVersionGLSL::TVersionGLSL):
+        (TVersionGLSL::visitSymbol):
+        (TVersionGLSL::visitConstantUnion):
+        (TVersionGLSL::visitBinary):
+        (TVersionGLSL::visitUnary):
+        (TVersionGLSL::visitSelection):
+        (TVersionGLSL::visitAggregate):
+        (TVersionGLSL::visitLoop):
+        (TVersionGLSL::visitBranch):
+        (TVersionGLSL::updateVersion):
+        * src/compiler/VersionGLSL.h: Added.
+        (TVersionGLSL::getVersion):
+        * src/compiler/generate_glslang_lexer.sh: Added.
+        * src/compiler/generate_glslang_parser.sh: Added.
+        * src/compiler/glslang.h: Added.
+        * src/compiler/glslang.l:
+        * src/compiler/glslang.y:
+        * src/compiler/glslang_lex.cpp: Added.
+        (yy_get_next_buffer):
+        (yy_get_previous_state):
+        (yy_try_NUL_trans):
+        (input):
+        (yyrestart):
+        (yy_switch_to_buffer):
+        (yy_load_buffer_state):
+        (yy_create_buffer):
+        (yy_delete_buffer):
+        (yy_init_buffer):
+        (yy_flush_buffer):
+        (yypush_buffer_state):
+        (yypop_buffer_state):
+        (yyensure_buffer_stack):
+        (yy_scan_buffer):
+        (yy_scan_string):
+        (yy_scan_bytes):
+        (yy_push_state):
+        (yy_pop_state):
+        (yy_top_state):
+        (yy_fatal_error):
+        (yyget_extra):
+        (yyget_lineno):
+        (yyget_column):
+        (yyget_in):
+        (yyget_out):
+        (yyget_leng):
+        (yyget_text):
+        (yyset_extra):
+        (yyset_lineno):
+        (yyset_column):
+        (yyset_in):
+        (yyset_out):
+        (yyget_debug):
+        (yyset_debug):
+        (yyget_lval):
+        (yyset_lval):
+        (yylex_init):
+        (yylex_init_extra):
+        (yy_init_globals):
+        (yylex_destroy):
+        (yy_flex_strncpy):
+        (yy_flex_strlen):
+        (yyalloc):
+        (yyrealloc):
+        (yyfree):
+        (string_input):
+        (check_type):
+        (reserved_word):
+        (yyerror):
+        (glslang_initialize):
+        (glslang_finalize):
+        (glslang_scan):
+        * src/compiler/glslang_tab.cpp: Added.
+        (yytnamerr):
+        (yysyntax_error):
+        (glslang_parse):
+        * src/compiler/glslang_tab.h: Added.
+        * src/compiler/intermOut.cpp:
+        (TOutputTraverser::TOutputTraverser):
+        (OutputTreeText):
+        (TOutputTraverser::visitSymbol):
+        (TOutputTraverser::visitBinary):
+        (TOutputTraverser::visitUnary):
+        (TOutputTraverser::visitAggregate):
+        (TOutputTraverser::visitSelection):
+        (TOutputTraverser::visitConstantUnion):
+        (TOutputTraverser::visitLoop):
+        (TOutputTraverser::visitBranch):
+        (TIntermediate::outputTree):
+        * src/compiler/intermediate.h:
+        (TIntermLoop::TIntermLoop):
+        (TIntermLoop::getType):
+        (TIntermLoop::getInit):
+        (TIntermLoop::getCondition):
+        (TIntermLoop::getExpression):
+        (TIntermLoop::getBody):
+        * src/compiler/localintermediate.h:
+        * src/compiler/osinclude.h:
+        (OS_GetTLSValue):
+        * src/compiler/ossource_nspr.cpp: Added.
+        (OS_AllocTLSIndex):
+        (OS_SetTLSValue):
+        (OS_FreeTLSIndex):
+        * src/compiler/preprocessor/compile.h:
+        * src/compiler/preprocessor/cpp.c:
+        (CPPdefine):
+        (CPPelse):
+        (CPPif):
+        (CPPifdef):
+        (CPPerror):
+        (CPPextension):
+        (readCPPline):
+        * src/compiler/preprocessor/preprocess.h:
+        * src/compiler/preprocessor/scanner.c:
+        (str_getch):
+        (str_ungetch):
+        (ScanFromString):
+        (lFloatConst):
+        (byte_scan):
+        (yylex_CPP):
+        (check_EOF):
+        * src/compiler/preprocessor/scanner.h:
+        * src/compiler/preprocessor/tokens.c:
+        (RecordToken):
+        (ReadToken):
+        * src/compiler/tools: Removed.
+        * src/compiler/unistd.h: Removed.
+        * src/compiler/util.cpp: Added.
+        (atof_dot):
+        * src/compiler/util.h: Added.
+        * src/libEGL/Config.cpp:
+        (egl::Config::set):
+        * src/libEGL/Display.cpp:
+        (egl::Display::Display):
+        (egl::Display::initialize):
+        (egl::Display::terminate):
+        (egl::Display::createDevice):
+        (egl::Display::resetDevice):
+        (egl::Display::createContext):
+        (egl::Display::destroyContext):
+        (egl::Display::getMinSwapInterval):
+        (egl::Display::getMaxSwapInterval):
+        (egl::Display::getDevice):
+        (egl::Display::getFloatTextureSupport):
+        (egl::Display::getHalfFloatTextureSupport):
+        (egl::Display::getLuminanceTextureSupport):
+        (egl::Display::getLuminanceAlphaTextureSupport):
+        (egl::Display::getBufferPool):
+        (egl::Display::getEventQuerySupport):
+        (egl::Display::getDefaultPresentParameters):
+        * src/libEGL/Display.h:
+        * src/libEGL/Surface.cpp:
+        (egl::Surface::Surface):
+        (egl::Surface::~Surface):
+        (egl::Surface::release):
+        (egl::Surface::resetSwapChain):
+        (egl::Surface::writeRecordableFlipState):
+        (egl::Surface::restoreState):
+        (egl::SurfaceWindowProc):
+        (egl::Surface::subclassWindow):
+        (egl::Surface::unsubclassWindow):
+        (egl::Surface::checkForOutOfDateSwapChain):
+        (egl::Surface::convertInterval):
+        (egl::Surface::swap):
+        (egl::Surface::getRenderTarget):
+        (egl::Surface::setSwapInterval):
+        * src/libEGL/Surface.h:
+        * src/libEGL/libEGL.cpp:
+        * src/libGLESv2/Blit.cpp:
+        (gl::Blit::copySurfaceToTexture):
+        (gl::Blit::setCommonBlitState):
+        * src/libGLESv2/Buffer.cpp:
+        (gl::Buffer::Buffer):
+        (gl::Buffer::~Buffer):
+        (gl::Buffer::bufferData):
+        (gl::Buffer::bufferSubData):
+        (gl::Buffer::getVertexBuffer):
+        (gl::Buffer::getIndexBuffer):
+        (gl::Buffer::invalidateStaticData):
+        * src/libGLESv2/Buffer.h:
+        * src/libGLESv2/Context.cpp:
+        (gl::Context::Context):
+        (gl::Context::~Context):
+        (gl::Context::makeCurrent):
+        (gl::Context::markAllStateDirty):
+        (gl::Context::setFragmentShaderDerivativeHint):
+        (gl::Context::setEnableVertexAttribArray):
+        (gl::Context::getVertexAttribState):
+        (gl::Context::getVertexAttributes):
+        (gl::Context::createFence):
+        (gl::Context::deleteFence):
+        (gl::Context::bindTexture2D):
+        (gl::Context::bindTextureCubeMap):
+        (gl::Context::getFence):
+        (gl::Context::getTexture2D):
+        (gl::Context::getTextureCubeMap):
+        (gl::Context::getSamplerTexture):
+        (gl::Context::getBooleanv):
+        (gl::Context::getIntegerv):
+        (gl::Context::getQueryParameterInfo):
+        (gl::Context::applyRenderTarget):
+        (gl::Context::applyState):
+        (gl::Context::lookupAttributeMapping):
+        (gl::Context::applyVertexBuffer):
+        (gl::Context::applyIndexBuffer):
+        (gl::Context::readPixels):
+        (gl::Context::clear):
+        (gl::Context::drawArrays):
+        (gl::Context::drawElements):
+        (gl::Context::finish):
+        (gl::Context::drawClosingLine):
+        (gl::Context::getMaximumVaryingVectors):
+        (gl::Context::getMaximumFragmentUniformVectors):
+        (gl::Context::supportsEventQueries):
+        (gl::Context::supportsFloatTextures):
+        (gl::Context::supportsFloatLinearFilter):
+        (gl::Context::supportsFloatRenderableTextures):
+        (gl::Context::supportsHalfFloatTextures):
+        (gl::Context::supportsHalfFloatLinearFilter):
+        (gl::Context::supportsHalfFloatRenderableTextures):
+        (gl::Context::getMaximumRenderbufferDimension):
+        (gl::Context::getMaximumTextureDimension):
+        (gl::Context::getMaximumCubeTextureDimension):
+        (gl::Context::getMaximumTextureLevel):
+        (gl::Context::supportsLuminanceTextures):
+        (gl::Context::supportsLuminanceAlphaTextures):
+        (gl::Context::supports32bitIndices):
+        (gl::Context::getIncompleteTexture):
+        (gl::Context::setVertexAttrib):
+        (gl::Context::initExtensionString):
+        (gl::Context::blitFramebuffer):
+        * src/libGLESv2/Context.h:
+        (gl::VertexAttribute::VertexAttribute):
+        (gl::VertexAttribute::typeSize):
+        (gl::VertexAttribute::stride):
+        * src/libGLESv2/Fence.cpp: Added.
+        (gl::Fence::Fence):
+        (gl::Fence::~Fence):
+        (gl::Fence::isFence):
+        (gl::Fence::setFence):
+        (gl::Fence::testFence):
+        (gl::Fence::finishFence):
+        (gl::Fence::getFenceiv):
+        * src/libGLESv2/Fence.h: Added.
+        * src/libGLESv2/Framebuffer.cpp:
+        (gl::Framebuffer::completeness):
+        (gl::DefaultFramebuffer::DefaultFramebuffer):
+        (gl::DefaultFramebuffer::completeness):
+        * src/libGLESv2/Program.cpp:
+        (gl::Program::Program):
+        (gl::Program::getSamplerMapping):
+        (gl::Program::getUniformLocation):
+        (gl::Program::setUniform1iv):
+        (gl::Program::applyUniforms):
+        (gl::Program::packVaryings):
+        (gl::Program::linkVaryings):
+        (gl::Program::link):
+        (gl::Program::defineUniform):
+        (gl::Program::createUniform):
+        (gl::Program::applyUniform1iv):
+        (gl::Program::resetInfoLog):
+        (gl::Program::unlink):
+        (gl::Program::getActiveAttribute):
+        (gl::Program::getActiveUniform):
+        (gl::Program::getDxDepthRangeLocation):
+        * src/libGLESv2/Program.h:
+        * src/libGLESv2/RefCountObject.cpp:
+        (gl::RefCountObject::~RefCountObject):
+        * src/libGLESv2/Renderbuffer.cpp:
+        (gl::RenderbufferStorage::RenderbufferStorage):
+        (gl::RenderbufferStorage::isFloatingPoint):
+        (gl::Colorbuffer::Colorbuffer):
+        (gl::DepthStencilbuffer::DepthStencilbuffer):
+        * src/libGLESv2/Renderbuffer.h:
+        * src/libGLESv2/Shader.cpp:
+        (gl::Shader::Shader):
+        (gl::Shader::parseVaryings):
+        (gl::Shader::compileToHLSL):
+        (gl::VertexShader::parseAttributes):
+        * src/libGLESv2/Texture.cpp:
+        (gl::Texture::Texture):
+        (gl::Texture::isFloatingPoint):
+        (gl::Texture::isRenderableFormat):
+        (gl::Texture::selectFormat):
+        (gl::Texture::loadImageData):
+        (gl::Texture::loadAlphaFloatImageData):
+        (gl::Texture::loadAlphaHalfFloatImageData):
+        (gl::Texture::loadLuminanceImageData):
+        (gl::Texture::loadLuminanceFloatImageData):
+        (gl::Texture::loadLuminanceHalfFloatImageData):
+        (gl::Texture::loadLuminanceAlphaImageData):
+        (gl::Texture::loadLuminanceAlphaFloatImageData):
+        (gl::Texture::loadLuminanceAlphaHalfFloatImageData):
+        (gl::Texture::loadRGBFloatImageData):
+        (gl::Texture::loadRGBHalfFloatImageData):
+        (gl::Texture::loadRGBAFloatImageData):
+        (gl::Texture::loadRGBAHalfFloatImageData):
+        (gl::Texture::createSurface):
+        (gl::Texture::setImage):
+        (gl::Texture::setCompressedImage):
+        (gl::Texture::subImage):
+        (gl::Texture::subImageCompressed):
+        (gl::Texture::copyNonRenderable):
+        (gl::Texture::getD3DFormat):
+        (gl::Texture::isRenderable):
+        (gl::Texture2D::Texture2D):
+        (gl::Texture2D::~Texture2D):
+        (gl::Texture2D::redefineTexture):
+        (gl::Texture2D::setImage):
+        (gl::Texture2D::setCompressedImage):
+        (gl::Texture2D::copyImage):
+        (gl::Texture2D::copySubImage):
+        (gl::Texture2D::isComplete):
+        (gl::Texture2D::createTexture):
+        (gl::Texture2D::convertToRenderTarget):
+        (gl::Texture2D::generateMipmaps):
+        (gl::Texture2D::getColorbuffer):
+        (gl::Texture2D::getRenderTarget):
+        (gl::TextureCubeMap::TextureCubeMap):
+        (gl::TextureCubeMap::~TextureCubeMap):
+        (gl::TextureCubeMap::subImage):
+        (gl::TextureCubeMap::subImageCompressed):
+        (gl::TextureCubeMap::isComplete):
+        (gl::TextureCubeMap::createTexture):
+        (gl::TextureCubeMap::convertToRenderTarget):
+        (gl::TextureCubeMap::redefineTexture):
+        (gl::TextureCubeMap::copyImage):
+        (gl::TextureCubeMap::copySubImage):
+        (gl::TextureCubeMap::generateMipmaps):
+        (gl::TextureCubeMap::getColorbuffer):
+        (gl::TextureCubeMap::getRenderTarget):
+        (gl::Texture::TextureColorbufferProxy::TextureColorbufferProxy):
+        (gl::Texture::TextureColorbufferProxy::isFloatingPoint):
+        * src/libGLESv2/Texture.h:
+        * src/libGLESv2/geometry/IndexDataManager.cpp:
+        (gl::IndexDataManager::IndexDataManager):
+        (gl::IndexDataManager::~IndexDataManager):
+        (gl::convertIndices):
+        (gl::computeRange):
+        (gl::IndexDataManager::prepareIndexData):
+        (gl::IndexDataManager::indexSize):
+        (gl::IndexDataManager::typeSize):
+        (gl::IndexBuffer::IndexBuffer):
+        (gl::IndexBuffer::~IndexBuffer):
+        (gl::IndexBuffer::getBuffer):
+        (gl::IndexBuffer::unmap):
+        (gl::StreamingIndexBuffer::StreamingIndexBuffer):
+        (gl::StreamingIndexBuffer::~StreamingIndexBuffer):
+        (gl::StreamingIndexBuffer::map):
+        (gl::StreamingIndexBuffer::reserveSpace):
+        (gl::StaticIndexBuffer::StaticIndexBuffer):
+        (gl::StaticIndexBuffer::~StaticIndexBuffer):
+        (gl::StaticIndexBuffer::map):
+        (gl::StaticIndexBuffer::reserveSpace):
+        (gl::StaticIndexBuffer::lookupType):
+        (gl::StaticIndexBuffer::lookupRange):
+        (gl::StaticIndexBuffer::addRange):
+        * src/libGLESv2/geometry/IndexDataManager.h:
+        (gl::IndexBuffer::size):
+        * src/libGLESv2/geometry/VertexDataManager.cpp:
+        (gl::VertexDataManager::VertexDataManager):
+        (gl::VertexDataManager::~VertexDataManager):
+        (gl::VertexDataManager::writeAttributeData):
+        (gl::VertexDataManager::prepareVertexData):
+        (gl::VertexDataManager::spaceRequired):
+        (gl::VertexDataManager::checkVertexCaps):
+        (gl::VertexDataManager::typeIndex):
+        (gl::VertexDataManager::setupAttributes):
+        (gl::VertexBuffer::VertexBuffer):
+        (gl::VertexBuffer::~VertexBuffer):
+        (gl::VertexBuffer::unmap):
+        (gl::VertexBuffer::getBuffer):
+        (gl::ConstantVertexBuffer::ConstantVertexBuffer):
+        (gl::ConstantVertexBuffer::~ConstantVertexBuffer):
+        (gl::ArrayVertexBuffer::ArrayVertexBuffer):
+        (gl::ArrayVertexBuffer::~ArrayVertexBuffer):
+        (gl::ArrayVertexBuffer::addRequiredSpace):
+        (gl::ArrayVertexBuffer::addRequiredSpaceFor):
+        (gl::StreamingVertexBuffer::StreamingVertexBuffer):
+        (gl::StreamingVertexBuffer::~StreamingVertexBuffer):
+        (gl::StreamingVertexBuffer::map):
+        (gl::StreamingVertexBuffer::reserveRequiredSpace):
+        (gl::StaticVertexBuffer::StaticVertexBuffer):
+        (gl::StaticVertexBuffer::~StaticVertexBuffer):
+        (gl::StaticVertexBuffer::map):
+        (gl::StaticVertexBuffer::reserveRequiredSpace):
+        (gl::StaticVertexBuffer::lookupAttribute):
+        (gl::VertexDataManager::formatConverter):
+        * src/libGLESv2/geometry/VertexDataManager.h:
+        (gl::ArrayVertexBuffer::size):
+        (gl::VertexDataManager::dirtyCurrentValue):
+        * src/libGLESv2/geometry/backend.cpp: Removed.
+        * src/libGLESv2/geometry/backend.h: Removed.
+        * src/libGLESv2/geometry/dx9.cpp: Removed.
+        * src/libGLESv2/geometry/dx9.h: Removed.
+        * src/libGLESv2/libGLESv2.cpp:
+        * src/libGLESv2/libGLESv2.def:
+        * src/libGLESv2/libGLESv2.vcproj:
+        * src/libGLESv2/utilities.cpp:
+        (gl::UniformComponentCount):
+        (gl::UniformComponentType):
+        (gl::ComputePixelSize):
+        (gl::CheckTextureFormatType):
+        (gl::IsColorRenderable):
+        (gl::IsDepthRenderable):
+        (gl::IsStencilRenderable):
+        (es2dx::GetAlphaSize):
+        (es2dx::GetRedSize):
+        (es2dx::GetGreenSize):
+        (es2dx::GetBlueSize):
+        (es2dx::GetDepthSize):
+        (es2dx::ConvertPrimitiveType):
+        (dx2es::ConvertBackBufferFormat):
+        (dx2es::ConvertDepthStencilFormat):
+        * src/libGLESv2/utilities.h:
+
 2011-01-17  Dan Bernstein  <mitz@apple.com>
 
         Rubber-stamped by Mark Rowe.
diff --git a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h
index e0a5cc8..d0664e4 100644
--- a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h
+++ b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h
@@ -14,6 +14,66 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+// Version number for shader translation API.
+// It is incremented everytime the API changes.
+#define SH_VERSION 103
+
+//
+// The names of the following enums have been derived by replacing GL prefix
+// with SH. For example, SH_INFO_LOG_LENGTH is equivalent to GL_INFO_LOG_LENGTH.
+// The enum values are also equal to the values of their GL counterpart. This
+// is done to make it easier for applications to use the shader library.
+//
+typedef enum {
+  SH_FRAGMENT_SHADER = 0x8B30,
+  SH_VERTEX_SHADER   = 0x8B31
+} ShShaderType;
+
+typedef enum {
+  SH_GLES2_SPEC = 0x8B40,
+  SH_WEBGL_SPEC = 0x8B41
+} ShShaderSpec;
+
+typedef enum {
+  SH_NONE           = 0,
+  SH_INT            = 0x1404,
+  SH_FLOAT          = 0x1406,
+  SH_FLOAT_VEC2     = 0x8B50,
+  SH_FLOAT_VEC3     = 0x8B51,
+  SH_FLOAT_VEC4     = 0x8B52,
+  SH_INT_VEC2       = 0x8B53,
+  SH_INT_VEC3       = 0x8B54,
+  SH_INT_VEC4       = 0x8B55,
+  SH_BOOL           = 0x8B56,
+  SH_BOOL_VEC2      = 0x8B57,
+  SH_BOOL_VEC3      = 0x8B58,
+  SH_BOOL_VEC4      = 0x8B59,
+  SH_FLOAT_MAT2     = 0x8B5A,
+  SH_FLOAT_MAT3     = 0x8B5B,
+  SH_FLOAT_MAT4     = 0x8B5C,
+  SH_SAMPLER_2D     = 0x8B5E,
+  SH_SAMPLER_CUBE   = 0x8B60
+} ShDataType;
+
+typedef enum {
+  SH_INFO_LOG_LENGTH             =  0x8B84,
+  SH_OBJECT_CODE_LENGTH          =  0x8B88,  // GL_SHADER_SOURCE_LENGTH
+  SH_ACTIVE_UNIFORMS             =  0x8B86,
+  SH_ACTIVE_UNIFORM_MAX_LENGTH   =  0x8B87,
+  SH_ACTIVE_ATTRIBUTES           =  0x8B89,
+  SH_ACTIVE_ATTRIBUTE_MAX_LENGTH =  0x8B8A
+} ShShaderInfo;
+
+// Compile options.
+typedef enum {
+  SH_VALIDATE               = 0,
+  SH_VALIDATE_LOOP_INDEXING = 0x0001,
+  SH_INTERMEDIATE_TREE      = 0x0002,
+  SH_OBJECT_CODE            = 0x0004,
+  SH_ATTRIBUTES_UNIFORMS    = 0x0008
+} ShCompileOptions;
+
 //
 // Driver must call this first, once, before doing any other
 // compiler operations.
@@ -25,23 +85,6 @@
 // If the function succeeds, the return value is nonzero, else zero.
 //
 int ShFinalize();
-//
-// Types of languages the compiler can consume.
-//
-typedef enum {
-    EShLangVertex,
-    EShLangFragment,
-    EShLangCount,
-} EShLanguage;
-
-//
-// The language specification compiler conforms to.
-// It currently supports OpenGL ES and WebGL specifications.
-//
-typedef enum {
-    EShSpecGLES2,
-    EShSpecWebGL,
-} EShSpec;
 
 //
 // Implementation dependent built-in resources (constants and extensions).
@@ -62,27 +105,12 @@
     // Extensions.
     // Set to 1 to enable the extension, else 0.
     int OES_standard_derivatives;
-} TBuiltInResource;
+} ShBuiltInResources;
 
 //
 // Initialize built-in resources with minimum expected values.
 //
-void ShInitBuiltInResource(TBuiltInResource* resources);
-
-//
-// Optimization level for the compiler.
-//
-typedef enum {
-    EShOptNoGeneration,
-    EShOptNone,
-    EShOptSimple,       // Optimizations that can be done quickly
-    EShOptFull,         // Optimizations that will take more time
-} EShOptimizationLevel;
-
-enum TDebugOptions {
-    EDebugOpNone               = 0x000,
-    EDebugOpIntermediate       = 0x001,  // Writes intermediate tree into info-log.
-};
+void ShInitBuiltInResources(ShBuiltInResources* resources);
 
 //
 // ShHandle held by but opaque to the driver.  It is allocated,
@@ -96,30 +124,130 @@
 //
 // Driver calls these to create and destroy compiler objects.
 //
-ShHandle ShConstructCompiler(EShLanguage, EShSpec, const TBuiltInResource*);
-void ShDestruct(ShHandle);
+// Returns the handle of constructed compiler.
+// Parameters:
+// type: Specifies the type of shader - SH_FRAGMENT_SHADER or SH_VERTEX_SHADER.
+// spec: Specifies the language spec the compiler must conform to -
+//       SH_GLES2_SPEC or SH_WEBGL_SPEC.
+// resources: Specifies the built-in resources.
+ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
+                             const ShBuiltInResources* resources);
+void ShDestruct(ShHandle handle);
 
 //
-// The return value of ShCompile is boolean, indicating
-// success or failure.
-//
-// The info-log should be written by ShCompile into 
-// ShHandle, so it can answer future queries.
+// Compiles the given shader source.
+// If the function succeeds, the return value is nonzero, else zero.
+// Parameters:
+// handle: Specifies the handle of compiler to be used.
+// shaderStrings: Specifies an array of pointers to null-terminated strings
+//                containing the shader source code.
+// numStrings: Specifies the number of elements in shaderStrings array.
+// compileOptions: A mask containing the following parameters:
+// SH_VALIDATE: Validates shader to ensure that it conforms to the spec
+//              specified during compiler construction.
+// SH_VALIDATE_LOOP_INDEXING: Validates loop and indexing in the shader to
+//                            ensure that they do not exceed the minimum
+//                            functionality mandated in GLSL 1.0 spec,
+//                            Appendix A, Section 4 and 5.
+//                            There is no need to specify this parameter when
+//                            compiling for WebGL - it is implied.
+// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
+//                       Can be queried by calling ShGetInfoLog().
+// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
+//                 Can be queried by calling ShGetObjectCode().
+// SH_ATTRIBUTES_UNIFORMS: Extracts attributes and uniforms.
+//                         Can be queried by calling ShGetActiveAttrib() and
+//                         ShGetActiveUniform().
 //
 int ShCompile(
-    const ShHandle,
+    const ShHandle handle,
     const char* const shaderStrings[],
     const int numStrings,
-    const EShOptimizationLevel,
-    int debugOptions
+    int compileOptions
     );
 
-//
-// All the following return 0 if the information is not
-// available in the object passed down, or the object is bad.
-//
-const char* ShGetInfoLog(const ShHandle);
-const char* ShGetObjectCode(const ShHandle);
+// Returns a parameter from a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+// pname: Specifies the parameter to query.
+// The following parameters are defined:
+// SH_INFO_LOG_LENGTH: the number of characters in the information log
+//                     including the null termination character.
+// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
+//                        including the null termination character.
+// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
+// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
+//                                 variable name including the null
+//                                 termination character.
+// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
+// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
+//                               variable name including the null
+//                               termination character.
+// 
+// params: Requested parameter
+void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params);
+
+// Returns nul-terminated information log for a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+// infoLog: Specifies an array of characters that is used to return
+//          the information log. It is assumed that infoLog has enough memory
+//          to accomodate the information log. The size of the buffer required
+//          to store the returned information log can be obtained by calling
+//          ShGetInfo with SH_INFO_LOG_LENGTH.
+void ShGetInfoLog(const ShHandle handle, char* infoLog);
+
+// Returns null-terminated object code for a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+// infoLog: Specifies an array of characters that is used to return
+//          the object code. It is assumed that infoLog has enough memory to
+//          accomodate the object code. The size of the buffer required to
+//          store the returned object code can be obtained by calling
+//          ShGetInfo with SH_OBJECT_CODE_LENGTH.
+void ShGetObjectCode(const ShHandle handle, char* objCode);
+
+// Returns information about an active attribute variable.
+// Parameters:
+// handle: Specifies the compiler
+// index: Specifies the index of the attribute variable to be queried.
+// length: Returns the number of characters actually written in the string
+//         indicated by name (excluding the null terminator) if a value other
+//         than NULL is passed.
+// size: Returns the size of the attribute variable.
+// type: Returns the data type of the attribute variable.
+// name: Returns a null terminated string containing the name of the
+//       attribute variable. It is assumed that name has enough memory to
+//       accomodate the attribute variable name. The size of the buffer
+//       required to store the attribute variable name can be obtained by
+//       calling ShGetInfo with SH_ACTIVE_ATTRIBUTE_MAX_LENGTH.
+void ShGetActiveAttrib(const ShHandle handle,
+                       int index,
+                       int* length,
+                       int* size,
+                       ShDataType* type,
+                       char* name);
+
+// Returns information about an active uniform variable.
+// Parameters:
+// handle: Specifies the compiler
+// index: Specifies the index of the uniform variable to be queried.
+// length: Returns the number of characters actually written in the string
+//         indicated by name (excluding the null terminator) if a value
+//         other than NULL is passed.
+// size: Returns the size of the uniform variable.
+// type: Returns the data type of the uniform variable.
+// name: Returns a null terminated string containing the name of the
+//       uniform variable. It is assumed that name has enough memory to
+//       accomodate the uniform variable name. The size of the buffer required
+//       to store the uniform variable name can be obtained by calling
+//       ShGetInfo with SH_ACTIVE_UNIFORMS_MAX_LENGTH.
+void ShGetActiveUniform(const ShHandle handle,
+                        int index,
+                        int* length,
+                        int* size,
+                        ShDataType* type,
+                        char* name);
 
 #ifdef __cplusplus
 }
diff --git a/Source/ThirdParty/ANGLE/src/common/debug.cpp b/Source/ThirdParty/ANGLE/src/common/debug.cpp
index d8d6ab8..3de5d4e 100644
--- a/Source/ThirdParty/ANGLE/src/common/debug.cpp
+++ b/Source/ThirdParty/ANGLE/src/common/debug.cpp
@@ -11,17 +11,22 @@
 #include <stdio.h>
 #include <stdarg.h>
 
+#ifndef TRACE_OUTPUT_FILE
+#define TRACE_OUTPUT_FILE "debug.txt"
+#endif
+
 static bool trace_on = true;
 
 namespace gl
 {
 void trace(const char *format, ...)
 {
+#if !defined(ANGLE_DISABLE_TRACE) 
     if (trace_on)
     {
         if (format)
         {
-            FILE *file = fopen("debug.txt", "a");
+            FILE *file = fopen(TRACE_OUTPUT_FILE, "a");
 
             if (file)
             {
@@ -34,5 +39,6 @@
             }
         }
     }
+#endif // !defined(ANGLE_DISABLE_TRACE)
 }
 }
diff --git a/Source/ThirdParty/ANGLE/src/common/debug.h b/Source/ThirdParty/ANGLE/src/common/debug.h
index 9a5135b..2c4ec70 100644
--- a/Source/ThirdParty/ANGLE/src/common/debug.h
+++ b/Source/ThirdParty/ANGLE/src/common/debug.h
@@ -19,7 +19,7 @@
 }
 
 // A macro to output a trace of a function call and its arguments to the debugging log
-#ifndef NDEBUG
+#if !defined(NDEBUG) && !defined(ANGLE_DISABLE_TRACE) 
     #define TRACE(message, ...) gl::trace("trace: %s"message"\n", __FUNCTION__, __VA_ARGS__)
 #else
     #define TRACE(...) ((void)0)
diff --git a/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp
index 855b092..d140b37 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp
@@ -11,9 +11,9 @@
 // compile object used by higher level code.  It returns
 // a subclass of TCompiler.
 //
-TCompiler* ConstructCompiler(EShLanguage language, EShSpec spec)
+TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec)
 {
-    return new TranslatorGLSL(language, spec);
+    return new TranslatorGLSL(type, spec);
 }
 
 //
diff --git a/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp
index 4db771d..e04e789 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp
@@ -11,9 +11,9 @@
 // compile object used by higher level code.  It returns
 // a subclass of TCompiler.
 //
-TCompiler* ConstructCompiler(EShLanguage language, EShSpec spec)
+TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec)
 {
-    return new TranslatorHLSL(language, spec);
+    return new TranslatorHLSL(type, spec);
 }
 
 //
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Common.h b/Source/ThirdParty/ANGLE/src/compiler/Common.h
index 65d0a51..27a5598 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Common.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/Common.h
@@ -14,9 +14,24 @@
 
 #include "compiler/PoolAlloc.h"
 
+// We need two pieces of information to report errors/warnings - string and
+// line number. We encode these into a single int so that it can be easily
+// incremented/decremented by lexer. The right SOURCE_LOC_LINE_SIZE bits store
+// line number while the rest store the string number. Since the shaders are
+// usually small, we should not run out of memory. SOURCE_LOC_LINE_SIZE
+// can be increased to alleviate this issue.
 typedef int TSourceLoc;
-const unsigned int SourceLocLineMask = 0xffff;
-const unsigned int SourceLocStringShift = 16;
+const unsigned int SOURCE_LOC_LINE_SIZE = 16;  // in bits.
+const unsigned int SOURCE_LOC_LINE_MASK = (1 << SOURCE_LOC_LINE_SIZE) - 1;
+
+inline TSourceLoc EncodeSourceLoc(int string, int line) {
+    return (string << SOURCE_LOC_LINE_SIZE) | (line & SOURCE_LOC_LINE_MASK);
+}
+
+inline void DecodeSourceLoc(TSourceLoc loc, int* string, int* line) {
+    if (string) *string = loc >> SOURCE_LOC_LINE_SIZE;
+    if (line) *line = loc & SOURCE_LOC_LINE_MASK;
+}
 
 //
 // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
@@ -71,6 +86,4 @@
     TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {}
 };
 
-typedef TMap<TString, TString> TPragmaTable;
-
 #endif // _COMMON_INCLUDED_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
new file mode 100644
index 0000000..649b457
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
@@ -0,0 +1,189 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/Initialize.h"
+#include "compiler/ParseHelper.h"
+#include "compiler/ShHandle.h"
+#include "compiler/ValidateLimitations.h"
+
+namespace {
+bool InitializeSymbolTable(
+    const TBuiltInStrings& builtInStrings,
+    ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
+    TInfoSink& infoSink, TSymbolTable& symbolTable)
+{
+    TIntermediate intermediate(infoSink);
+    TExtensionBehavior extBehavior;
+    TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, infoSink);
+
+    GlobalParseContext = &parseContext;
+
+    assert(symbolTable.isEmpty());       
+    //
+    // Parse the built-ins.  This should only happen once per
+    // language symbol table.
+    //
+    // Push the symbol table to give it an initial scope.  This
+    // push should not have a corresponding pop, so that built-ins
+    // are preserved, and the test for an empty table fails.
+    //
+    symbolTable.push();
+
+    for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
+    {
+        const char* builtInShaders = i->c_str();
+        int builtInLengths = static_cast<int>(i->size());
+        if (builtInLengths <= 0)
+          continue;
+
+        if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0)
+        {
+            infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
+            return false;
+        }
+    }
+
+    IdentifyBuiltIns(type, spec, resources, symbolTable);
+
+    return true;
+}
+
+class TScopedPoolAllocator {
+public:
+    TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
+        : mAllocator(allocator), mPushPopAllocator(pushPop) {
+        if (mPushPopAllocator) mAllocator->push();
+        SetGlobalPoolAllocator(mAllocator);
+    }
+    ~TScopedPoolAllocator() {
+        SetGlobalPoolAllocator(NULL);
+        if (mPushPopAllocator) mAllocator->pop();
+    }
+
+private:
+    TPoolAllocator* mAllocator;
+    bool mPushPopAllocator;
+};
+}  // namespace
+
+TShHandleBase::TShHandleBase() {
+    allocator.push();
+    SetGlobalPoolAllocator(&allocator);
+}
+
+TShHandleBase::~TShHandleBase() {
+    SetGlobalPoolAllocator(NULL);
+    allocator.popAll();
+}
+
+TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
+    : shaderType(type),
+      shaderSpec(spec) 
+{
+}
+
+TCompiler::~TCompiler()
+{
+}
+
+bool TCompiler::Init(const ShBuiltInResources& resources)
+{
+    TScopedPoolAllocator scopedAlloc(&allocator, false);
+
+    // Generate built-in symbol table.
+    if (!InitBuiltInSymbolTable(resources))
+        return false;
+    InitExtensionBehavior(resources, extensionBehavior);
+
+    return true;
+}
+
+bool TCompiler::compile(const char* const shaderStrings[],
+                        const int numStrings,
+                        int compileOptions)
+{
+    TScopedPoolAllocator scopedAlloc(&allocator, true);
+    clearResults();
+
+    if (numStrings == 0)
+        return true;
+
+    // If compiling for WebGL, validate loop and indexing as well.
+    if (shaderSpec == SH_WEBGL_SPEC)
+        compileOptions |= SH_VALIDATE_LOOP_INDEXING;
+
+    TIntermediate intermediate(infoSink);
+    TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
+                               shaderType, shaderSpec, infoSink);
+    GlobalParseContext = &parseContext;
+
+    // We preserve symbols at the built-in level from compile-to-compile.
+    // Start pushing the user-defined symbols at global level.
+    symbolTable.push();
+    if (!symbolTable.atGlobalLevel())
+        infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
+
+    // Parse shader.
+    bool success =
+        (PaParseStrings(numStrings, shaderStrings, NULL, &parseContext) == 0) &&
+        (parseContext.treeRoot != NULL);
+    if (success) {
+        TIntermNode* root = parseContext.treeRoot;
+        success = intermediate.postProcess(root);
+
+        if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
+            success = validateLimitations(root);
+
+        if (success && (compileOptions & SH_INTERMEDIATE_TREE))
+            intermediate.outputTree(root);
+
+        if (success && (compileOptions & SH_OBJECT_CODE))
+            translate(root);
+
+        if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
+            collectAttribsUniforms(root);
+    }
+
+    // Cleanup memory.
+    intermediate.remove(parseContext.treeRoot);
+    // Ensure symbol table is returned to the built-in level,
+    // throwing away all but the built-ins.
+    while (!symbolTable.atBuiltInLevel())
+        symbolTable.pop();
+
+    return success;
+}
+
+bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
+{
+    TBuiltIns builtIns;
+
+    builtIns.initialize(shaderType, shaderSpec, resources);
+    return InitializeSymbolTable(builtIns.getBuiltInStrings(),
+        shaderType, shaderSpec, resources, infoSink, symbolTable);
+}
+
+void TCompiler::clearResults()
+{
+    infoSink.info.erase();
+    infoSink.obj.erase();
+    infoSink.debug.erase();
+
+    attribs.clear();
+    uniforms.clear();
+}
+
+bool TCompiler::validateLimitations(TIntermNode* root) {
+    ValidateLimitations validate(shaderType, infoSink.info);
+    root->traverse(&validate);
+    return validate.numErrors() == 0;
+}
+
+void TCompiler::collectAttribsUniforms(TIntermNode* root)
+{
+    CollectAttribsUniforms collect(attribs, uniforms);
+    root->traverse(&collect);
+}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h b/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h
new file mode 100644
index 0000000..da96c24
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _EXTENSION_BEHAVIOR_INCLUDED_
+#define _EXTENSION_BEHAVIOR_INCLUDED_
+
+#include "compiler/Common.h"
+
+typedef enum {
+    EBhRequire,
+    EBhEnable,
+    EBhWarn,
+    EBhDisable
+} TBehavior;
+
+typedef TMap<TString, TBehavior> TExtensionBehavior;
+
+#endif // _EXTENSION_TABLE_INCLUDED_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp b/Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp
index 317a88f..ba32f78 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp
@@ -32,8 +32,8 @@
 }
 
 void TInfoSinkBase::location(TSourceLoc loc) {
-    int string = loc >> SourceLocStringShift;
-    int line = loc & SourceLocLineMask;
+    int string = 0, line = 0;
+    DecodeSourceLoc(loc, &string, &line);
 
     TPersistStringStream stream;
     if (line)
diff --git a/Source/ThirdParty/ANGLE/src/compiler/InfoSink.h b/Source/ThirdParty/ANGLE/src/compiler/InfoSink.h
index 4762778..e2224e9 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/InfoSink.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/InfoSink.h
@@ -91,6 +91,7 @@
     }
 
     void erase() { sink.clear(); }
+    int size() { return static_cast<int>(sink.size()); }
 
     const TPersistString& str() const { return sink; }
     const char* c_str() const { return sink.c_str(); }
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp b/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp
index 6bfcf4f..12b53fe 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp
@@ -311,15 +311,6 @@
     s.append(TString("bvec4 not(bvec4 x);"));
 
     //
-    // Texture Functions.
-    //
-    s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
-    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
-    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
-
-    s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
-
-    //
     // Noise functions.
     //
     //s.append(TString("float noise1(float x);"));
@@ -342,7 +333,6 @@
     //s.append(TString("vec4 noise4(vec3  x);"));
     //s.append(TString("vec4 noise4(vec4  x);"));
 
-    s.append(TString("\n"));
     return s;
 }
 
@@ -351,7 +341,7 @@
 // Prototypes for built-in functions seen by vertex shaders only.
 //
 //============================================================================
-static TString BuiltInFunctionsVertex()
+static TString BuiltInFunctionsVertex(const ShBuiltInResources& resources)
 {
     TString s;
 
@@ -363,12 +353,18 @@
     //
     // Texture Functions.
     //
-    s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
-    s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
-    s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
-    s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
+    if (resources.MaxVertexTextureImageUnits > 0) {
+        s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
+        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
+        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
+        s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
 
-    s.append(TString("\n"));
+        s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
+        s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
+        s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
+        s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
+    }
+
     return s;
 }
 
@@ -377,34 +373,40 @@
 // Prototypes for built-in functions seen by fragment shaders only.
 //
 //============================================================================
-static TString BuiltInFunctionsFragment()
+static TString BuiltInFunctionsFragment(const ShBuiltInResources& resources)
 {
     TString s;
 
     //
     // Texture Functions.
     //
+    s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
+    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
+    s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
+    s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
+
     s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
     s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
     s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
     s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
 
-    //s.append(TString("float dFdx(float p);"));
-    //s.append(TString("vec2  dFdx(vec2  p);"));
-    //s.append(TString("vec3  dFdx(vec3  p);"));
-    //s.append(TString("vec4  dFdx(vec4  p);"));
+    if (resources.OES_standard_derivatives) {
+        s.append(TString("float dFdx(float p);"));
+        s.append(TString("vec2  dFdx(vec2  p);"));
+        s.append(TString("vec3  dFdx(vec3  p);"));
+        s.append(TString("vec4  dFdx(vec4  p);"));
 
-    //s.append(TString("float dFdy(float p);"));
-    //s.append(TString("vec2  dFdy(vec2  p);"));
-    //s.append(TString("vec3  dFdy(vec3  p);"));
-    //s.append(TString("vec4  dFdy(vec4  p);"));
+        s.append(TString("float dFdy(float p);"));
+        s.append(TString("vec2  dFdy(vec2  p);"));
+        s.append(TString("vec3  dFdy(vec3  p);"));
+        s.append(TString("vec4  dFdy(vec4  p);"));
 
-    s.append(TString("float fwidth(float p);"));
-    s.append(TString("vec2  fwidth(vec2  p);"));
-    s.append(TString("vec3  fwidth(vec3  p);"));
-    s.append(TString("vec4  fwidth(vec4  p);"));
+        s.append(TString("float fwidth(float p);"));
+        s.append(TString("vec2  fwidth(vec2  p);"));
+        s.append(TString("vec3  fwidth(vec3  p);"));
+        s.append(TString("vec4  fwidth(vec4  p);"));
+    }
 
-    s.append(TString("\n"));
     return s;
 }
 
@@ -427,7 +429,6 @@
     s.append(TString("};"));
     s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
 
-    s.append(TString("\n"));
     return s;
 }
 
@@ -443,7 +444,6 @@
     s.append(TString("precision highp int;"));
     s.append(TString("precision highp float;"));
 
-    s.append(TString("\n"));
     return s;
 }
 
@@ -459,7 +459,6 @@
     s.append(TString("precision mediump int;"));
     // No default precision for float in fragment shaders
 
-    s.append(TString("\n"));
     return s;
 }
 
@@ -468,7 +467,7 @@
 // Implementation dependent built-in constants.
 //
 //============================================================================
-static TString BuiltInConstants(const TBuiltInResource &resources)
+static TString BuiltInConstants(const ShBuiltInResources &resources)
 {
     TStringStream s;
 
@@ -485,20 +484,21 @@
     return s.str();
 }
 
-void TBuiltIns::initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources)
+void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec,
+                           const ShBuiltInResources& resources)
 {
-    switch (language) {
-    case EShLangFragment:
+    switch (type) {
+    case SH_FRAGMENT_SHADER:
         builtInStrings.push_back(DefaultPrecisionFragment());
         builtInStrings.push_back(BuiltInFunctionsCommon());
-        builtInStrings.push_back(BuiltInFunctionsFragment());
+        builtInStrings.push_back(BuiltInFunctionsFragment(resources));
         builtInStrings.push_back(StandardUniforms());
         break;
 
-    case EShLangVertex:
+    case SH_VERTEX_SHADER:
         builtInStrings.push_back(DefaultPrecisionVertex());
         builtInStrings.push_back(BuiltInFunctionsCommon());
-        builtInStrings.push_back(BuiltInFunctionsVertex());
+        builtInStrings.push_back(BuiltInFunctionsVertex(resources));
         builtInStrings.push_back(StandardUniforms());
         break;
 
@@ -508,14 +508,16 @@
     builtInStrings.push_back(BuiltInConstants(resources));
 }
 
-void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources, TSymbolTable& symbolTable)
+void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
+                      const ShBuiltInResources& resources,
+                      TSymbolTable& symbolTable)
 {
     //
     // First, insert some special built-in variables that are not in 
     // the built-in header files.
     //
-    switch(language) {
-    case EShLangFragment:
+    switch(type) {
+    case SH_FRAGMENT_SHADER:
         symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"),                   TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
         symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"),                 TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
         symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"),                   TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
@@ -523,7 +525,7 @@
         symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"),                  TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
         break;
 
-    case EShLangVertex:
+    case SH_VERTEX_SHADER:
         symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"),    TType(EbtFloat, EbpHigh, EvqPosition,    4)));
         symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"),   TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
         break;
@@ -591,20 +593,26 @@
     symbolTable.relateToOperator("all",          EOpAll);
 
     // Map language-specific operators.
-    switch(language) {
-    case EShLangVertex:
+    switch(type) {
+    case SH_VERTEX_SHADER:
         break;
-    case EShLangFragment:
-        //symbolTable.relateToOperator("dFdx",   EOpDPdx);    // OES_standard_derivatives extension
-        //symbolTable.relateToOperator("dFdy",   EOpDPdy);    // OES_standard_derivatives extension
-        //symbolTable.relateToOperator("fwidth", EOpFwidth);  // OES_standard_derivatives extension
+    case SH_FRAGMENT_SHADER:
+        if (resources.OES_standard_derivatives) {
+            symbolTable.relateToOperator("dFdx",   EOpDFdx);
+            symbolTable.relateToOperator("dFdy",   EOpDFdy);
+            symbolTable.relateToOperator("fwidth", EOpFwidth);
+
+            symbolTable.relateToExtension("dFdx", "GL_OES_standard_derivatives");
+            symbolTable.relateToExtension("dFdy", "GL_OES_standard_derivatives");
+            symbolTable.relateToExtension("fwidth", "GL_OES_standard_derivatives");
+        }
         break;
     default: break;
     }
 
     // Finally add resource-specific variables.
-    switch(language) {
-    case EShLangFragment: {
+    switch(type) {
+    case SH_FRAGMENT_SHADER: {
             // Set up gl_FragData.  The array size.
             TType fragData(EbtFloat, EbpMedium, EvqFragColor,   4, false, true);
             fragData.setArraySize(resources.MaxDrawBuffers);
@@ -615,3 +623,9 @@
     }
 }
 
+void InitExtensionBehavior(const ShBuiltInResources& resources,
+                           TExtensionBehavior& extBehavior)
+{
+    if (resources.OES_standard_derivatives)
+        extBehavior["GL_OES_standard_derivatives"] = EBhDisable;
+}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Initialize.h b/Source/ThirdParty/ANGLE/src/compiler/Initialize.h
index c078659..8b0adc6 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Initialize.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/Initialize.h
@@ -17,17 +17,19 @@
 public:
     POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
 
-    void initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources);
+    void initialize(ShShaderType type, ShShaderSpec spec,
+                    const ShBuiltInResources& resources);
     const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; }
 
 protected:
     TBuiltInStrings builtInStrings;
 };
 
-void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
+void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
+                      const ShBuiltInResources& resources,
                       TSymbolTable& symbolTable);
 
-extern "C" int InitPreprocessor(void);
-extern "C" int FinalizePreprocessor(void);
+void InitExtensionBehavior(const ShBuiltInResources& resources,
+                           TExtensionBehavior& extensionBehavior);
 
 #endif // _INITIALIZE_INCLUDED_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp b/Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp
index 34a6f3c..a13877f 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp
@@ -229,9 +229,9 @@
 
 		if(it->rightToLeft)
 		{
-			if(terminal)
+			if(expr)
 			{
-				terminal->traverse(it);
+				expr->traverse(it);
 			}
 
 			if(body)
@@ -239,16 +239,16 @@
 				body->traverse(it);
 			}
 
-			if(test)
+			if(cond)
 			{
-				test->traverse(it);
+				cond->traverse(it);
 			}
 		}
 		else
 		{
-			if(test)
+			if(cond)
 			{
-				test->traverse(it);
+				cond->traverse(it);
 			}
 
 			if(body)
@@ -256,9 +256,9 @@
 				body->traverse(it);
 			}
 
-			if(terminal)
+			if(expr)
 			{
-				terminal->traverse(it);
+				expr->traverse(it);
 			}
 		}
 
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp b/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp
index 5ebd919..ea71234 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp
@@ -22,6 +22,101 @@
     return left > right ? left : right;
 }
 
+const char* getOperatorString(TOperator op) {
+    switch (op) {
+      case EOpInitialize: return "=";
+      case EOpAssign: return "=";
+      case EOpAddAssign: return "+=";
+      case EOpSubAssign: return "-=";
+      case EOpDivAssign: return "/=";
+
+      // Fall-through.
+      case EOpMulAssign: 
+      case EOpVectorTimesMatrixAssign:
+      case EOpVectorTimesScalarAssign:
+      case EOpMatrixTimesScalarAssign:
+      case EOpMatrixTimesMatrixAssign: return "*=";
+
+      // Fall-through.
+      case EOpIndexDirect:
+      case EOpIndexIndirect: return "[]";
+
+      case EOpIndexDirectStruct: return ".";
+      case EOpVectorSwizzle: return ".";
+      case EOpAdd: return "+";
+      case EOpSub: return "-";
+      case EOpMul: return "*";
+      case EOpDiv: return "/";
+      case EOpMod: UNIMPLEMENTED(); break;
+      case EOpEqual: return "==";
+      case EOpNotEqual: return "!=";
+      case EOpLessThan: return "<";
+      case EOpGreaterThan: return ">";
+      case EOpLessThanEqual: return "<=";
+      case EOpGreaterThanEqual: return ">=";
+
+      // Fall-through.
+      case EOpVectorTimesScalar:
+      case EOpVectorTimesMatrix:
+      case EOpMatrixTimesVector:
+      case EOpMatrixTimesScalar:
+      case EOpMatrixTimesMatrix: return "*";
+
+      case EOpLogicalOr: return "||";
+      case EOpLogicalXor: return "^^";
+      case EOpLogicalAnd: return "&&";
+      case EOpNegative: return "-";
+      case EOpVectorLogicalNot: return "not";
+      case EOpLogicalNot: return "!";
+      case EOpPostIncrement: return "++";
+      case EOpPostDecrement: return "--";
+      case EOpPreIncrement: return "++";
+      case EOpPreDecrement: return "--";
+
+      // Fall-through.
+      case EOpConvIntToBool:
+      case EOpConvFloatToBool: return "bool";
+ 
+      // Fall-through.
+      case EOpConvBoolToFloat:
+      case EOpConvIntToFloat: return "float";
+ 
+      // Fall-through.
+      case EOpConvFloatToInt:
+      case EOpConvBoolToInt: return "int";
+
+      case EOpRadians: return "radians";
+      case EOpDegrees: return "degrees";
+      case EOpSin: return "sin";
+      case EOpCos: return "cos";
+      case EOpTan: return "tan";
+      case EOpAsin: return "asin";
+      case EOpAcos: return "acos";
+      case EOpAtan: return "atan";
+      case EOpExp: return "exp";
+      case EOpLog: return "log";
+      case EOpExp2: return "exp2";
+      case EOpLog2: return "log2";
+      case EOpSqrt: return "sqrt";
+      case EOpInverseSqrt: return "inversesqrt";
+      case EOpAbs: return "abs";
+      case EOpSign: return "sign";
+      case EOpFloor: return "floor";
+      case EOpCeil: return "ceil";
+      case EOpFract: return "fract";
+      case EOpLength: return "length";
+      case EOpNormalize: return "normalize";
+      case EOpDFdx: return "dFdx";
+      case EOpDFdy: return "dFdy";
+      case EOpFwidth: return "fwidth";
+      case EOpAny: return "any";
+      case EOpAll: return "all";
+
+      default: break;
+    }
+    return "";
+}
+
 ////////////////////////////////////////////////////////////////////////////
 //
 // First set of functions are to help build the intermediate representation.
@@ -51,18 +146,23 @@
 TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable)
 {
     switch (op) {
+        case EOpEqual:
+        case EOpNotEqual:
+            if (left->isArray())
+                return 0;
+            break;
         case EOpLessThan:
         case EOpGreaterThan:
         case EOpLessThanEqual:
         case EOpGreaterThanEqual:
-            if (left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector() || left->getType().getBasicType() == EbtStruct) {
+            if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) {
                 return 0;
             }
             break;
         case EOpLogicalOr:
         case EOpLogicalXor:
         case EOpLogicalAnd:
-            if (left->getType().getBasicType() != EbtBool || left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector()) {
+            if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) {
                 return 0;
             }
             break;
@@ -70,7 +170,7 @@
         case EOpSub:
         case EOpDiv:
         case EOpMul:
-            if (left->getType().getBasicType() == EbtStruct || left->getType().getBasicType() == EbtBool)
+            if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
                 return 0;
         default: break;
     }
@@ -78,8 +178,10 @@
     //
     // First try converting the children to compatible types.
     //
-
-    if (!(left->getType().getStruct() && right->getType().getStruct())) {
+    if (left->getType().getStruct() && right->getType().getStruct()) {
+        if (left->getType() != right->getType())
+            return 0;
+    } else {
         TIntermTyped* child = addConversion(op, left->getType(), right);
         if (child)
             right = child;
@@ -90,12 +192,8 @@
             else
                 return 0;
         }
-    } else {
-        if (left->getType() != right->getType())
-            return 0;
     }
 
-
     //
     // Need a new node holding things together then.  Make
     // one and promote it to the right type.
@@ -107,18 +205,16 @@
 
     node->setLeft(left);
     node->setRight(right);
-    if (! node->promote(infoSink))
+    if (!node->promote(infoSink))
         return 0;
 
-    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
-    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
-
     //
     // See if we can fold constants.
     //
-
     TIntermTyped* typedReturnNode = 0;
-    if ( leftTempConstant && rightTempConstant) {
+    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
+    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
+    if (leftTempConstant && rightTempConstant) {
         typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
 
         if (typedReturnNode)
@@ -602,9 +698,9 @@
 //
 // Create loop nodes.
 //
-TIntermNode* TIntermediate::addLoop(TIntermNode *init, TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line)
+TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, TSourceLoc line)
 {
-    TIntermNode* node = new TIntermLoop(init, body, test, terminal, testFirst);
+    TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
     node->setLine(line);
 
     return node;
@@ -630,7 +726,7 @@
 // This is to be executed once the final root is put on top by the parsing
 // process.
 //
-bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
+bool TIntermediate::postProcess(TIntermNode* root)
 {
     if (root == 0)
         return true;
@@ -760,6 +856,12 @@
 //
 bool TIntermBinary::promote(TInfoSink& infoSink)
 {
+    // This function only handles scalars, vectors, and matrices.
+    if (left->isArray() || right->isArray()) {
+        infoSink.info.message(EPrefixInternalError, "Invalid operation for arrays", getLine());
+        return false;
+    }
+
     // GLSL ES 2.0 does not support implicit type casting.
     // So the basic type should always match.
     if (left->getBasicType() != right->getBasicType())
@@ -781,40 +883,6 @@
         getTypePointer()->setQualifier(EvqTemporary);
     }
 
-    //
-    // Array operations.
-    //
-    if (left->isArray() || right->isArray()) {
-        //
-        // Arrays types have to be exact matches.
-        //
-        if (left->getType() != right->getType())
-            return false;
-
-        switch (op) {
-            //
-            // Promote to conditional
-            //
-            case EOpEqual:
-            case EOpNotEqual:
-                setType(TType(EbtBool, EbpUndefined));
-                break;
-
-            //
-            // Set array information.
-            //
-            case EOpAssign:
-            case EOpInitialize:
-                getTypePointer()->setArraySize(left->getType().getArraySize());
-                getTypePointer()->setArrayInformationType(left->getType().getArrayInformationType());
-                break;
-
-            default:
-                return false;
-        }
-        return true;
-    }
-
     int size = std::max(left->getNominalSize(), right->getNominalSize());
 
     //
diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp
index fd263b6..23476f2 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp
@@ -374,6 +374,10 @@
         case EOpLength: writeTriplet(visit, "length(", NULL, ")"); break;
         case EOpNormalize: writeTriplet(visit, "normalize(", NULL, ")"); break;
 
+        case EOpDFdx: writeTriplet(visit, "dFdx(", NULL, ")"); break;
+        case EOpDFdy: writeTriplet(visit, "dFdy(", NULL, ")"); break;
+        case EOpFwidth: writeTriplet(visit, "fwidth(", NULL, ")"); break;
+
         case EOpAny: writeTriplet(visit, "any(", NULL, ")"); break;
         case EOpAll: writeTriplet(visit, "all(", NULL, ")"); break;
 
@@ -608,23 +612,32 @@
 
     incrementDepth();
     // Loop header.
-    if (node->testFirst())  // for loop
+    TLoopType loopType = node->getType();
+    if (loopType == ELoopFor)  // for loop
     {
         out << "for (";
         if (node->getInit())
             node->getInit()->traverse(this);
         out << "; ";
 
-        ASSERT(node->getTest() != NULL);
-        node->getTest()->traverse(this);
+        if (node->getCondition())
+            node->getCondition()->traverse(this);
         out << "; ";
 
-        if (node->getTerminal())
-            node->getTerminal()->traverse(this);
+        if (node->getExpression())
+            node->getExpression()->traverse(this);
+        out << ")\n";
+    }
+    else if (loopType == ELoopWhile)  // while loop
+    {
+        out << "while (";
+        ASSERT(node->getCondition() != NULL);
+        node->getCondition()->traverse(this);
         out << ")\n";
     }
     else  // do-while loop
     {
+        ASSERT(loopType == ELoopDoWhile);
         out << "do\n";
     }
 
@@ -632,11 +645,11 @@
     visitCodeBlock(node->getBody());
 
     // Loop footer.
-    if (!node->testFirst())  // while loop
+    if (loopType == ELoopDoWhile)  // do-while loop
     {
         out << "while (";
-        ASSERT(node->getTest() != NULL);
-        node->getTest()->traverse(this);
+        ASSERT(node->getCondition() != NULL);
+        node->getCondition()->traverse(this);
         out << ");\n";
     }
     decrementDepth();
diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp
index 8b8a4e6..57e99d2 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp
@@ -9,6 +9,7 @@
 #include "compiler/debug.h"
 #include "compiler/InfoSink.h"
 #include "compiler/UnfoldSelect.h"
+#include "compiler/SearchSymbol.h"
 
 #include <stdio.h>
 #include <algorithm>
@@ -64,7 +65,7 @@
 
     mScopeDepth = 0;
 
-    mArgumentIndex = 0;
+    mUniqueIndex = 0;
 }
 
 OutputHLSL::~OutputHLSL()
@@ -96,7 +97,7 @@
 
 void OutputHLSL::header()
 {
-    EShLanguage language = mContext.language;
+    ShShaderType shaderType = mContext.shaderType;
     TInfoSinkBase &out = mHeader;
 
     for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++)
@@ -109,7 +110,7 @@
         out << *constructor;
     }
 
-    if (language == EShLangFragment)
+    if (shaderType == SH_FRAGMENT_SHADER)
     {
         TString uniforms;
         TString varyings;
@@ -361,7 +362,8 @@
                "    float diff;\n"
                "};\n"
                "\n"
-               "uniform gl_DepthRangeParameters gl_DepthRange;\n"
+               "uniform float3 dx_DepthRange;"
+               "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
                "\n";
     }
 
@@ -653,7 +655,39 @@
     switch (node->getOp())
     {
       case EOpAssign:                  outputTriplet(visit, "(", " = ", ")");           break;
-      case EOpInitialize:              outputTriplet(visit, "", " = ", "");             break;
+      case EOpInitialize:
+        if (visit == PreVisit)
+        {
+            // GLSL allows to write things like "float x = x;" where a new variable x is defined
+            // and the value of an existing variable x is assigned. HLSL uses C semantics (the
+            // new variable is created before the assignment is evaluated), so we need to convert
+            // this to "float t = x, x = t;".
+
+            TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
+            TIntermTyped *expression = node->getRight();
+
+            sh::SearchSymbol searchSymbol(symbolNode->getSymbol());
+            expression->traverse(&searchSymbol);
+            bool sameSymbol = searchSymbol.foundMatch();
+
+            if (sameSymbol)
+            {
+                // Type already printed
+                out << "t" + str(mUniqueIndex) + " = ";
+                expression->traverse(this);
+                out << ", ";
+                symbolNode->traverse(this);
+                out << " = t" + str(mUniqueIndex);
+
+                mUniqueIndex++;
+                return false;
+            }
+        }
+        else if (visit == InVisit)
+        {
+            out << " = ";
+        }
+        break;
       case EOpAddAssign:               outputTriplet(visit, "(", " += ", ")");          break;
       case EOpSubAssign:               outputTriplet(visit, "(", " -= ", ")");          break;
       case EOpMulAssign:               outputTriplet(visit, "(", " *= ", ")");          break;
@@ -933,9 +967,9 @@
       case EOpFract:            outputTriplet(visit, "frac(", "", ")");      break;
       case EOpLength:           outputTriplet(visit, "length(", "", ")");    break;
       case EOpNormalize:        outputTriplet(visit, "normalize(", "", ")"); break;
-//    case EOpDPdx:             outputTriplet(visit, "ddx(", "", ")");       break;
-//    case EOpDPdy:             outputTriplet(visit, "ddy(", "", ")");       break;
-//    case EOpFwidth:           outputTriplet(visit, "fwidth(", "", ")");    break;        
+      case EOpDFdx:             outputTriplet(visit, "ddx(", "", ")");       break;
+      case EOpDFdy:             outputTriplet(visit, "ddy(", "", ")");       break;
+      case EOpFwidth:           outputTriplet(visit, "fwidth(", "", ")");    break;        
       case EOpAny:              outputTriplet(visit, "any(", "", ")");       break;
       case EOpAll:              outputTriplet(visit, "all(", "", ")");       break;
       default: UNREACHABLE();
@@ -946,7 +980,7 @@
 
 bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
 {
-    EShLanguage language = mContext.language;
+    ShShaderType shaderType = mContext.shaderType;
     TInfoSinkBase &out = mBody;
 
     switch (node->getOp())
@@ -1392,7 +1426,7 @@
 
     TInfoSinkBase &out = mBody;
 
-    if (!node->testFirst())
+    if (node->getType() == ELoopDoWhile)
     {
         out << "do\n"
                "{\n";
@@ -1404,14 +1438,14 @@
             mUnfoldSelect->traverse(node->getInit());
         }
         
-        if (node->getTest())
+        if (node->getCondition())
         {
-            mUnfoldSelect->traverse(node->getTest());
+            mUnfoldSelect->traverse(node->getCondition());
         }
         
-        if (node->getTerminal())
+        if (node->getExpression())
         {
-            mUnfoldSelect->traverse(node->getTerminal());
+            mUnfoldSelect->traverse(node->getExpression());
         }
 
         out << "for(";
@@ -1423,16 +1457,16 @@
 
         out << "; ";
 
-        if (node->getTest())
+        if (node->getCondition())
         {
-            node->getTest()->traverse(this);
+            node->getCondition()->traverse(this);
         }
 
         out << "; ";
 
-        if (node->getTerminal())
+        if (node->getExpression())
         {
-            node->getTerminal()->traverse(this);
+            node->getExpression()->traverse(this);
         }
 
         out << ")\n"
@@ -1446,11 +1480,11 @@
 
     out << "}\n";
 
-    if (!node->testFirst())
+    if (node->getType() == ELoopDoWhile)
     {
         out << "while(\n";
 
-        node->getTest()->traverse(this);
+        node->getCondition()->traverse(this);
 
         out << ")";
     }
@@ -1565,9 +1599,9 @@
     }
 
     // Parse comparator and limit value
-    if (index != NULL && node->getTest())
+    if (index != NULL && node->getCondition())
     {
-        TIntermBinary *test = node->getTest()->getAsBinaryNode();
+        TIntermBinary *test = node->getCondition()->getAsBinaryNode();
         
         if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
         {
@@ -1585,10 +1619,10 @@
     }
 
     // Parse increment
-    if (index != NULL && comparator != EOpNull && node->getTerminal())
+    if (index != NULL && comparator != EOpNull && node->getExpression())
     {
-        TIntermBinary *binaryTerminal = node->getTerminal()->getAsBinaryNode();
-        TIntermUnary *unaryTerminal = node->getTerminal()->getAsUnaryNode();
+        TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
+        TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
         
         if (binaryTerminal)
         {
@@ -1711,7 +1745,7 @@
 
     if (name.empty())   // HLSL demands named arguments, also for prototypes
     {
-        name = "x" + str(mArgumentIndex++);
+        name = "x" + str(mUniqueIndex++);
     }
     else
     {
diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h
index dc3c482..ddbd077 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h
@@ -120,7 +120,7 @@
     ScopeBracket mScopeBracket;
     unsigned int mScopeDepth;
 
-    int mArgumentIndex;   // For creating unique argument names
+    int mUniqueIndex;   // For creating unique names
 };
 }
 
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp
index 407226b..53f3fa8 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp
@@ -9,9 +9,35 @@
 #include <stdarg.h>
 #include <stdio.h>
 
+#include "compiler/glslang.h"
 #include "compiler/osinclude.h"
 #include "compiler/InitializeParseContext.h"
 
+extern "C" {
+extern int InitPreprocessor();
+extern int FinalizePreprocessor();
+extern void PredefineIntMacro(const char *name, int value);
+}
+
+static void ReportInfo(TInfoSinkBase& sink,
+                       TPrefixType type, TSourceLoc loc,
+                       const char* reason, const char* token, 
+                       const char* extraInfo)
+{
+    /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
+    sink.prefix(type);
+    sink.location(loc);
+    sink << "'" << token <<  "' : " << reason << " " << extraInfo << "\n";
+}
+
+static void DefineExtensionMacros(const TExtensionBehavior& extBehavior)
+{
+    for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
+         iter != extBehavior.end(); ++iter) {
+        PredefineIntMacro(iter->first.c_str(), 1);
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////
 //
 // Sub- vector and matrix fields
@@ -176,26 +202,34 @@
 //
 // Used by flex/bison to output all syntax and parsing errors.
 //
-void TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken, 
-                          const char *szExtraInfoFormat, ...)
+void TParseContext::error(TSourceLoc loc,
+                          const char* reason, const char* token, 
+                          const char* extraInfoFormat, ...)
 {
-    char szExtraInfo[400];
+    char extraInfo[512];
     va_list marker;
+    va_start(marker, extraInfoFormat);
+    vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
 
-    va_start(marker, szExtraInfoFormat);
-
-    vsnprintf(szExtraInfo, sizeof(szExtraInfo), szExtraInfoFormat, marker);
-
-    /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
-    infoSink.info.prefix(EPrefixError);
-    infoSink.info.location(nLine);
-    infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
+    ReportInfo(infoSink.info, EPrefixError, loc, reason, token, extraInfo);
 
     va_end(marker);
-
     ++numErrors;
 }
 
+void TParseContext::warning(TSourceLoc loc,
+                            const char* reason, const char* token,
+                            const char* extraInfoFormat, ...) {
+    char extraInfo[512];
+    va_list marker;
+    va_start(marker, extraInfoFormat);
+    vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
+
+    ReportInfo(infoSink.info, EPrefixWarning, loc, reason, token, extraInfo);
+
+    va_end(marker);
+}
+
 //
 // Same error message for all places assignments don't work.
 //
@@ -415,7 +449,7 @@
             error(line, reservedErrMsg, "gl_", "");
             return true;
         }
-        if (spec == EShSpecWebGL) {
+        if (shaderSpec == SH_WEBGL_SPEC) {
             if (identifier.substr(0, 6) == TString("webgl_")) {
                 error(line, reservedErrMsg, "webgl_", "");
                 return true;
@@ -471,17 +505,18 @@
     bool matrixInMatrix = false;
     bool arrayArg = false;
     for (int i = 0; i < function.getParamCount(); ++i) {
-        size += function[i].type->getObjectSize();
+        const TParameter& param = function.getParam(i);
+        size += param.type->getObjectSize();
         
-        if (constructingMatrix && function[i].type->isMatrix())
+        if (constructingMatrix && param.type->isMatrix())
             matrixInMatrix = true;
         if (full)
             overFull = true;
         if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
             full = true;
-        if (function[i].type->getQualifier() != EvqConst)
+        if (param.type->getQualifier() != EvqConst)
             constType = false;
-        if (function[i].type->isArray())
+        if (param.type->isArray())
             arrayArg = true;
     }
     
@@ -510,7 +545,7 @@
         return true;
     }
     
-    if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->size() != function.getParamCount()) {
+    if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) {
         error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
         return true;
     }
@@ -674,14 +709,11 @@
 //
 bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
 {
-    if (type.qualifier == EvqAttribute) {
+    if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
         error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), "");
         return true;
     }
 
-    if (type.qualifier == EvqConst && extensionErrorCheck(line, "GL_3DL_array_objects"))
-        return true;
-
     return false;
 }
 
@@ -886,16 +918,22 @@
     return false;
 }
 
-bool TParseContext::extensionErrorCheck(int line, const char* extension)
-{       
-    if (extensionBehavior[extension] == EBhWarn) {
-        infoSink.info.message(EPrefixWarning, ("extension " + TString(extension) + " is being used").c_str(), line);
-        return false;
-    }
-    if (extensionBehavior[extension] == EBhDisable) {
-        error(line, "extension", extension, "is disabled");
+bool TParseContext::extensionErrorCheck(int line, const TString& extension)
+{
+    TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension);
+    if (iter == extensionBehavior.end()) {
+        error(line, "extension", extension.c_str(), "is not supported");
         return true;
     }
+    if (iter->second == EBhDisable) {
+        error(line, "extension", extension.c_str(), "is disabled");
+        return true;
+    }
+    if (iter->second == EBhWarn) {
+        TString msg = "extension " + extension + " is being used";
+        infoSink.info.message(EPrefixWarning, msg.c_str(), line);
+        return false;
+    }
 
     return false;
 }
@@ -1021,6 +1059,7 @@
 
 bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
 {
+    ASSERT(aggrNode != NULL);
     if (!aggrNode->isConstructor())
         return false;
 
@@ -1028,13 +1067,10 @@
 
     // check if all the child nodes are constants so that they can be inserted into 
     // the parent node
-    if (aggrNode) {
-        TIntermSequence &childSequenceVector = aggrNode->getSequence() ;
-        for (TIntermSequence::iterator p = childSequenceVector.begin(); 
-                                    p != childSequenceVector.end(); p++) {
-            if (!(*p)->getAsTyped()->getAsConstantUnion())
-                return false;
-        }
+    TIntermSequence &sequence = aggrNode->getSequence() ;
+    for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
+        if (!(*p)->getAsTyped()->getAsConstantUnion())
+            return false;
     }
 
     return allConstant;
@@ -1379,16 +1415,29 @@
 }
 
 //
-// Initialize all supported extensions to disable
+// Parse an array of strings using yyparse.
 //
-void TParseContext::initializeExtensionBehavior()
-{
-    //
-    // example code: extensionBehavior["test"] = EBhDisable; // where "test" is the name of 
-    // supported extension
-    //
-    extensionBehavior["GL_ARB_texture_rectangle"] = EBhRequire;
-    extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
+// Returns 0 for success.
+//
+int PaParseStrings(int count, const char* const string[], const int length[],
+                   TParseContext* context) {
+    if ((count == 0) || (string == NULL))
+        return 1;
+
+    // setup preprocessor.
+    if (InitPreprocessor())
+        return 1;
+    DefineExtensionMacros(context->extensionBehavior);
+
+    if (glslang_initialize(context))
+        return 1;
+
+    glslang_scan(count, string, length, context);
+    int error = glslang_parse(context);
+
+    glslang_finalize(context);
+    FinalizePreprocessor();
+    return (error == 0) && (context->numErrors == 0) ? 0 : 1;
 }
 
 OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h
index 792333f..cb6e0d0 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h
@@ -6,9 +6,10 @@
 #ifndef _PARSER_HELPER_INCLUDED_
 #define _PARSER_HELPER_INCLUDED_
 
+#include "compiler/ExtensionBehavior.h"
+#include "compiler/localintermediate.h"
 #include "compiler/ShHandle.h"
 #include "compiler/SymbolTable.h"
-#include "compiler/localintermediate.h"
 
 struct TMatrixFields {
     bool wholeRow;
@@ -17,13 +18,6 @@
     int col;
 };
 
-typedef enum {
-    EBhRequire,
-    EBhEnable,
-    EBhWarn,
-    EBhDisable
-} TBehavior;
-
 struct TPragma {
     TPragma(bool o, bool d) : optimize(o), debug(d) { }
     bool optimize;
@@ -36,15 +30,16 @@
 // they can be passed to the parser without needing a global.
 //
 struct TParseContext {
-    TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage l, EShSpec s, TInfoSink& is) :
-            intermediate(interm), symbolTable(symt), infoSink(is), language(l), spec(s), treeRoot(0),
+    TParseContext(TSymbolTable& symt, const TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, TInfoSink& is) :
+            intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), treeRoot(0),
             recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
-            inTypeParen(false), contextPragma(true, false) {  }
+            inTypeParen(false), scanner(NULL), contextPragma(true, false) {  }
     TIntermediate& intermediate; // to hold and build a parse tree
     TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
+    TExtensionBehavior extensionBehavior;  // mapping between supported extensions and current behavior.
     TInfoSink& infoSink;
-    EShLanguage language;        // vertex or fragment language (future: pack or unpack)
-    EShSpec spec;                // The language specification compiler conforms to - GLES2 or WebGL.
+    ShShaderType shaderType;              // vertex or fragment language (future: pack or unpack)
+    ShShaderSpec shaderSpec;              // The language specification compiler conforms to - GLES2 or WebGL.
     TIntermNode* treeRoot;       // root of parse tree being created
     bool recoveredFromError;     // true if a parse error has occurred, but we continue to parse
     int numErrors;
@@ -53,11 +48,11 @@
     bool inTypeParen;            // true if in parentheses, looking only for an identifier
     const TType* currentFunctionType;  // the return type of the function that's currently being parsed
     bool functionReturnsValue;   // true if a non-void function has a return
-    TMap<TString, TBehavior> extensionBehavior;
-    void initializeExtensionBehavior();
 
-    void error(TSourceLoc, const char *szReason, const char *szToken,
-               const char *szExtraInfoFormat, ...);
+    void error(TSourceLoc loc, const char *reason, const char* token,
+               const char* extraInfoFormat, ...);
+    void warning(TSourceLoc loc, const char* reason, const char* token,
+                 const char* extraInfoFormat, ...);
     bool reservedErrorCheck(int line, const TString& identifier);
     void recover();
 
@@ -86,7 +81,7 @@
     bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
     bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
     bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
-    bool extensionErrorCheck(int line, const char*);
+    bool extensionErrorCheck(int line, const TString&);
     const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
     bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
                             TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
@@ -100,16 +95,14 @@
     TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
     TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
     bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
+    void* scanner;
     struct TPragma contextPragma;
     TString HashErrMsg;
     bool AfterEOF;
 };
 
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
-void PaReservedWord();
-int PaIdentOrType(TString& id, TParseContext&, TSymbol*&);
-int PaParseComment(int &lineno, TParseContext&);
-void setInitialState();
+int PaParseStrings(int count, const char* const string[], const int length[],
+                   TParseContext* context);
 
 typedef TParseContext* TParseContextPointer;
 extern TParseContextPointer& GetGlobalParseContext();
diff --git a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp
index 7e348ca..93e21e4 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp
@@ -22,14 +22,10 @@
     if (globalPools)
         return;
 
-    TPoolAllocator *globalPoolAllocator = new TPoolAllocator(true);
-
     TThreadGlobalPools* threadData = new TThreadGlobalPools();
-    
-    threadData->globalPoolAllocator = globalPoolAllocator;
-        
-    OS_SetTLSValue(PoolIndex, threadData);     
-    globalPoolAllocator->push();
+    threadData->globalPoolAllocator = 0;
+
+    OS_SetTLSValue(PoolIndex, threadData);
 }
 
 void FreeGlobalPools()
@@ -38,9 +34,7 @@
     TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));    
     if (!globalPools)
         return;
-    
-    GlobalPoolAllocator.popAll();
-    delete &GlobalPoolAllocator;       
+ 
     delete globalPools;
 }
 
@@ -66,7 +60,7 @@
     return *threadData->globalPoolAllocator;
 }
 
-void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator)
+void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
 {
     TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
 
@@ -77,13 +71,13 @@
 // Implement the functionality of the TPoolAllocator class, which
 // is documented in PoolAlloc.h.
 //
-TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignment) : 
-    global(g),
+TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : 
     pageSize(growthIncrement),
     alignment(allocationAlignment),
     freeList(0),
     inUseList(0),
-    numCalls(0)
+    numCalls(0),
+    totalBytes(0)
 {
     //
     // Don't allow page sizes we know are smaller than all common
@@ -123,24 +117,14 @@
 
 TPoolAllocator::~TPoolAllocator()
 {
-    if (!global) {
-        //
-        // Then we know that this object is not being 
-        // allocated after other, globally scoped objects
-        // that depend on it.  So we can delete the "in use" memory.
-        //
-        while (inUseList) {
-            tHeader* next = inUseList->nextPage;
-            inUseList->~tHeader();
-            delete [] reinterpret_cast<char*>(inUseList);
-            inUseList = next;
-        }
+    while (inUseList) {
+        tHeader* next = inUseList->nextPage;
+        inUseList->~tHeader();
+        delete [] reinterpret_cast<char*>(inUseList);
+        inUseList = next;
     }
 
-    //
-    // Always delete the free list memory - it can't be being
-    // (correctly) referenced, whether the pool allocator was
-    // global or not.  We should not check the guard blocks
+    // We should not check the guard blocks
     // here, because we did it already when the block was
     // placed into the free list.
     //
@@ -315,4 +299,4 @@
 {
     for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
         alloc->check();
-}
+}
\ No newline at end of file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h
index 645db78..051dc00 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h
@@ -115,7 +115,7 @@
 //
 class TPoolAllocator {
 public:
-    TPoolAllocator(bool global = false, int growthIncrement = 8*1024, int allocationAlignment = 16);
+    TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16);
 
     //
     // Don't call the destructor just to free up the memory, call pop()
@@ -194,7 +194,6 @@
         return TAllocation::offsetAllocation(memory);
     }
 
-    bool global;            // should be true if this object is globally scoped
     size_t pageSize;        // granularity of allocation from the OS
     size_t alignment;       // all returned allocations will be aligned at 
                             // this granularity, which will be a power of 2
@@ -220,18 +219,15 @@
 // different times.  But a simple use is to have a global pop
 // with everyone using the same global allocator.
 //
-typedef TPoolAllocator* PoolAllocatorPointer;
 extern TPoolAllocator& GetGlobalPoolAllocator();
+extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
 #define GlobalPoolAllocator GetGlobalPoolAllocator()
 
-
 struct TThreadGlobalPools
 {
     TPoolAllocator* globalPoolAllocator;
 };
 
-void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator);
-
 //
 // This STL compatible allocator is intended to be used as the allocator
 // parameter to templatized STL containers, like vector and map.
@@ -301,4 +297,4 @@
     TPoolAllocator& allocator;
 };
 
-#endif // _POOLALLOC_INCLUDED_
+#endif // _POOLALLOC_INCLUDED_
\ No newline at end of file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.cpp b/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.cpp
new file mode 100644
index 0000000..9368f1a4
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.cpp
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SearchSymbol is an AST traverser to detect the use of a given symbol name
+//
+
+#include "compiler/SearchSymbol.h"
+
+#include "compiler/InfoSink.h"
+#include "compiler/OutputHLSL.h"
+
+namespace sh
+{
+SearchSymbol::SearchSymbol(const TString &symbol) : mSymbol(symbol)
+{
+    match = false;
+}
+
+void SearchSymbol::traverse(TIntermNode *node)
+{
+    node->traverse(this);
+}
+
+void SearchSymbol::visitSymbol(TIntermSymbol *symbolNode)
+{
+    if (symbolNode->getSymbol() == mSymbol)
+    {
+        match = true;
+    }
+}
+
+bool SearchSymbol::foundMatch() const
+{
+    return match;
+}
+}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.h b/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.h
new file mode 100644
index 0000000..6bc0b90
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.h
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SearchSymbol is an AST traverser to detect the use of a given symbol name
+//
+
+#ifndef COMPILER_SEARCHSYMBOL_H_
+#define COMPILER_SEARCHSYMBOL_H_
+
+#include "compiler/intermediate.h"
+#include "compiler/ParseHelper.h"
+
+namespace sh
+{
+class SearchSymbol : public TIntermTraverser
+{
+  public:
+    SearchSymbol(const TString &symbol);
+
+    void traverse(TIntermNode *node);
+    void visitSymbol(TIntermSymbol *symbolNode);
+
+    bool foundMatch() const;
+
+  protected:
+    const TString &mSymbol;
+    bool match;
+};
+}
+
+#endif   // COMPILER_SEARCHSYMBOL_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h b/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h
index 5ef5d30..e65c1ee 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h
@@ -16,20 +16,26 @@
 
 #include "GLSLANG/ShaderLang.h"
 
+#include "compiler/ExtensionBehavior.h"
 #include "compiler/InfoSink.h"
 #include "compiler/SymbolTable.h"
+#include "compiler/VariableInfo.h"
 
 class TCompiler;
-class TIntermNode;
 
 //
 // The base class used to back handles returned to the driver.
 //
 class TShHandleBase {
 public:
-    TShHandleBase() { }
-    virtual ~TShHandleBase() { }
+    TShHandleBase();
+    virtual ~TShHandleBase();
     virtual TCompiler* getAsCompiler() { return 0; }
+
+protected:
+    // Memory allocator. Allocates and tracks memory required by the compiler.
+    // Deallocates all memory when compiler is destructed.
+    TPoolAllocator allocator;
 };
 
 //
@@ -38,27 +44,49 @@
 //
 class TCompiler : public TShHandleBase {
 public:
-    TCompiler(EShLanguage l, EShSpec s) : language(l), spec(s) { }
-    virtual ~TCompiler() { }
-
-    EShLanguage getLanguage() const { return language; }
-    EShSpec getSpec() const { return spec; }
-    TSymbolTable& getSymbolTable() { return symbolTable; }
-    TInfoSink& getInfoSink() { return infoSink; }
-
-    virtual bool compile(TIntermNode* root) = 0;
-
+    TCompiler(ShShaderType type, ShShaderSpec spec);
+    virtual ~TCompiler();
     virtual TCompiler* getAsCompiler() { return this; }
 
+    bool Init(const ShBuiltInResources& resources);
+    bool compile(const char* const shaderStrings[],
+                 const int numStrings,
+                 int compileOptions);
+
+    // Get results of the last compilation.
+    TInfoSink& getInfoSink() { return infoSink; }
+    const TVariableInfoList& getAttribs() const { return attribs; }
+    const TVariableInfoList& getUniforms() const { return uniforms; }
+
 protected:
-    EShLanguage language;
-    EShSpec spec;
+    ShShaderType getShaderType() const { return shaderType; }
+    ShShaderSpec getShaderSpec() const { return shaderSpec; }
+    // Initialize symbol-table with built-in symbols.
+    bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
+    // Clears the results from the previous compilation.
+    void clearResults();
+    // Returns true if the given shader does not exceed the minimum
+    // functionality mandated in GLSL 1.0 spec Appendix A.
+    bool validateLimitations(TIntermNode* root);
+    // Collect info for all attribs and uniforms.
+    void collectAttribsUniforms(TIntermNode* root);
+    // Translate to object code.
+    virtual void translate(TIntermNode* root) = 0;
+
+private:
+    ShShaderType shaderType;
+    ShShaderSpec shaderSpec;
 
     // Built-in symbol table for the given language, spec, and resources.
     // It is preserved from compile-to-compile.
     TSymbolTable symbolTable;
-    // Output sink.
-    TInfoSink infoSink;
+    // Built-in extensions with default behavior.
+    TExtensionBehavior extensionBehavior;
+
+    // Results of compilation.
+    TInfoSink infoSink;  // Output sink.
+    TVariableInfoList attribs;  // Active attributes in the compiled shader.
+    TVariableInfoList uniforms;  // Active uniforms in the compiled shader.
 };
 
 //
@@ -70,7 +98,7 @@
 // destroy the machine dependent objects, which contain the
 // above machine independent information.
 //
-TCompiler* ConstructCompiler(EShLanguage, EShSpec);
+TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec);
 void DeleteCompiler(TCompiler*);
 
-#endif // _SHHANDLE_INCLUDED_
+#endif // _SHHANDLE_INCLUDED_
\ No newline at end of file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp b/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp
index e0c646a..6cac61d 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp
@@ -11,79 +11,56 @@
 
 #include "GLSLANG/ShaderLang.h"
 
-#include "compiler/Initialize.h"
 #include "compiler/InitializeDll.h"
-#include "compiler/ParseHelper.h"
 #include "compiler/ShHandle.h"
-#include "compiler/SymbolTable.h"
-
-static bool InitializeSymbolTable(
-        const TBuiltInStrings& builtInStrings,
-        EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
-        TInfoSink& infoSink, TSymbolTable& symbolTable)
-{
-    TIntermediate intermediate(infoSink);
-    TParseContext parseContext(symbolTable, intermediate, language, spec, infoSink);
-
-    GlobalParseContext = &parseContext;
-
-    setInitialState();
-
-    assert(symbolTable.isEmpty());       
-    //
-    // Parse the built-ins.  This should only happen once per
-    // language symbol table.
-    //
-    // Push the symbol table to give it an initial scope.  This
-    // push should not have a corresponding pop, so that built-ins
-    // are preserved, and the test for an empty table fails.
-    //
-    symbolTable.push();
-    
-    //Initialize the Preprocessor
-    if (InitPreprocessor())
-    {
-        infoSink.info.message(EPrefixInternalError,  "Unable to intialize the Preprocessor");
-        return false;
-    }
-
-    for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
-    {
-        const char* builtInShaders[1];
-        int builtInLengths[1];
-
-        builtInShaders[0] = (*i).c_str();
-        builtInLengths[0] = (int) (*i).size();
-
-        if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0)
-        {
-            infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
-            return false;
-        }
-    }
-
-    IdentifyBuiltIns(language, spec, resources, symbolTable);
-
-    FinalizePreprocessor();
-
-    return true;
-}
-
-static bool GenerateBuiltInSymbolTable(
-        EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
-        TInfoSink& infoSink, TSymbolTable& symbolTable)
-{
-    TBuiltIns builtIns;
-
-    builtIns.initialize(language, spec, resources);
-    return InitializeSymbolTable(builtIns.getBuiltInStrings(), language, spec, resources, infoSink, symbolTable);
-}
 
 //
 // This is the platform independent interface between an OGL driver
 // and the shading language compiler.
 //
 
+static int getVariableMaxLength(const TVariableInfoList& varList)
+{
+    TString::size_type maxLen = 0;
+    for (TVariableInfoList::const_iterator i = varList.begin();
+         i != varList.end(); ++i)
+    {
+        maxLen = std::max(maxLen, i->name.size());
+    }
+    // Add 1 to include null-termination character.
+    return static_cast<int>(maxLen) + 1;
+}
+
+static void getVariableInfo(ShShaderInfo varType,
+                            const ShHandle handle,
+                            int index,
+                            int* length,
+                            int* size,
+                            ShDataType* type,
+                            char* name)
+{
+    if (!handle || !size || !type || !name)
+        return;
+    ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
+           (varType == SH_ACTIVE_UNIFORMS));
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+    TCompiler* compiler = base->getAsCompiler();
+    if (compiler == 0)
+        return;
+
+    const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
+        compiler->getAttribs() : compiler->getUniforms();
+    if (index < 0 || index >= static_cast<int>(varList.size()))
+        return;
+
+    const TVariableInfo& varInfo = varList[index];
+    if (length) *length = varInfo.name.size();
+    *size = varInfo.size;
+    *type = varInfo.type;
+    strcpy(name, varInfo.name.c_str());
+}
+
 //
 // Driver must call this first, once, before doing any other
 // compiler operations.
@@ -110,7 +87,7 @@
 //
 // Initialize built-in resources with minimum expected values.
 //
-void ShInitBuiltInResource(TBuiltInResource* resources)
+void ShInitBuiltInResources(ShBuiltInResources* resources)
 {
     // Constants.
     resources->MaxVertexAttribs = 8;
@@ -129,18 +106,19 @@
 //
 // Driver calls these to create and destroy compiler objects.
 //
-ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources)
+ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
+                             const ShBuiltInResources* resources)
 {
     if (!InitThread())
         return 0;
 
-    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, spec));
+    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
     TCompiler* compiler = base->getAsCompiler();
     if (compiler == 0)
         return 0;
 
     // Generate built-in symbol table.
-    if (!GenerateBuiltInSymbolTable(language, spec, *resources, compiler->getInfoSink(), compiler->getSymbolTable())) {
+    if (!compiler->Init(*resources)) {
         ShDestruct(base);
         return 0;
     }
@@ -170,9 +148,7 @@
     const ShHandle handle,
     const char* const shaderStrings[],
     const int numStrings,
-    const EShOptimizationLevel optLevel,
-    int debugOptions
-    )
+    int compileOptions)
 {
     if (!InitThread())
         return 0;
@@ -184,128 +160,95 @@
     TCompiler* compiler = base->getAsCompiler();
     if (compiler == 0)
         return 0;
-    
-    GlobalPoolAllocator.push();
-    TInfoSink& infoSink = compiler->getInfoSink();
-    infoSink.info.erase();
-    infoSink.debug.erase();
-    infoSink.obj.erase();
 
-    if (numStrings == 0)
-        return 1;
-
-    TIntermediate intermediate(infoSink);
-    TSymbolTable& symbolTable = compiler->getSymbolTable();
-
-    TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->getSpec(), infoSink);
-    parseContext.initializeExtensionBehavior();
-    GlobalParseContext = &parseContext;
- 
-    setInitialState();
-
-    InitPreprocessor();
-    //
-    // Parse the application's shaders.  All the following symbol table
-    // work will be throw-away, so push a new allocation scope that can
-    // be thrown away, then push a scope for the current shader's globals.
-    //
-    bool success = true;
-
-    symbolTable.push();
-    if (!symbolTable.atGlobalLevel())
-        parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
-
-    int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext);
-    if (ret)
-        success = false;
-
-    if (success && parseContext.treeRoot) {
-        if (optLevel == EShOptNoGeneration)
-            parseContext.infoSink.info.message(EPrefixNone, "No errors.  No code generation was requested.");
-        else {
-            success = intermediate.postProcess(parseContext.treeRoot, parseContext.language);
-
-            if (success) {
-
-                if (debugOptions & EDebugOpIntermediate)
-                    intermediate.outputTree(parseContext.treeRoot);
-
-                //
-                // Call the machine dependent compiler
-                //
-                if (!compiler->compile(parseContext.treeRoot))
-                    success = false;
-            }
-        }
-    } else if (!success) {
-        parseContext.infoSink.info.prefix(EPrefixError);
-        parseContext.infoSink.info << parseContext.numErrors << " compilation errors.  No code generated.\n\n";
-        success = false;
-        if (debugOptions & EDebugOpIntermediate)
-            intermediate.outputTree(parseContext.treeRoot);
-    } else if (!parseContext.treeRoot) {
-        parseContext.error(1, "Unexpected end of file.", "", "");
-        parseContext.infoSink.info << parseContext.numErrors << " compilation errors.  No code generated.\n\n";
-        success = false;
-        if (debugOptions & EDebugOpIntermediate)
-            intermediate.outputTree(parseContext.treeRoot);
-    }
-
-    intermediate.remove(parseContext.treeRoot);
-
-    //
-    // Ensure symbol table is returned to the built-in level,
-    // throwing away all but the built-ins.
-    //
-    while (!symbolTable.atBuiltInLevel())
-        symbolTable.pop();
-
-    FinalizePreprocessor();
-    //
-    // Throw away all the temporary memory used by the compilation process.
-    //
-    GlobalPoolAllocator.pop();
-
+    bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
     return success ? 1 : 0;
 }
 
+void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
+{
+    if (!handle || !params)
+        return;
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+    TCompiler* compiler = base->getAsCompiler();
+    if (!compiler) return;
+
+    switch(pname)
+    {
+    case SH_INFO_LOG_LENGTH:
+        *params = compiler->getInfoSink().info.size() + 1;
+        break;
+    case SH_OBJECT_CODE_LENGTH:
+        *params = compiler->getInfoSink().obj.size() + 1;
+        break;
+    case SH_ACTIVE_UNIFORMS:
+        *params = compiler->getUniforms().size();
+        break;
+    case SH_ACTIVE_UNIFORM_MAX_LENGTH:
+        *params = getVariableMaxLength(compiler->getUniforms());
+        break;
+    case SH_ACTIVE_ATTRIBUTES:
+        *params = compiler->getAttribs().size();
+        break;
+    case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+        *params = getVariableMaxLength(compiler->getAttribs());
+        break;
+
+    default: UNREACHABLE();
+    }
+}
+
 //
 // Return any compiler log of messages for the application.
 //
-const char* ShGetInfoLog(const ShHandle handle)
+void ShGetInfoLog(const ShHandle handle, char* infoLog)
 {
-    if (!InitThread())
-        return 0;
-
-    if (handle == 0)
-        return 0;
+    if (!handle || !infoLog)
+        return;
 
     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TInfoSink* infoSink = 0;
+    TCompiler* compiler = base->getAsCompiler();
+    if (!compiler) return;
 
-    if (base->getAsCompiler())
-        infoSink = &(base->getAsCompiler()->getInfoSink());
-
-    infoSink->info << infoSink->debug.c_str();
-    return infoSink->info.c_str();
+    TInfoSink& infoSink = compiler->getInfoSink();
+    strcpy(infoLog, infoSink.info.c_str());
 }
 
 //
 // Return any object code.
 //
-const char* ShGetObjectCode(const ShHandle handle)
+void ShGetObjectCode(const ShHandle handle, char* objCode)
 {
-    if (!InitThread())
-        return 0;
-
-    if (handle == 0)
-        return 0;
+    if (!handle || !objCode)
+        return;
 
     TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-    TInfoSink* infoSink;
+    TCompiler* compiler = base->getAsCompiler();
+    if (!compiler) return;
 
-    if (base->getAsCompiler())
-        infoSink = &(base->getAsCompiler()->getInfoSink());
+    TInfoSink& infoSink = compiler->getInfoSink();
+    strcpy(objCode, infoSink.obj.c_str());
+}
 
-    return infoSink->obj.c_str();
+void ShGetActiveAttrib(const ShHandle handle,
+                       int index,
+                       int* length,
+                       int* size,
+                       ShDataType* type,
+                       char* name)
+{
+    getVariableInfo(SH_ACTIVE_ATTRIBUTES,
+                    handle, index, length, size, type, name);
+}
+
+void ShGetActiveUniform(const ShHandle handle,
+                        int index,
+                        int* length,
+                        int* size,
+                        ShDataType* type,
+                        char* name)
+{
+    getVariableInfo(SH_ACTIVE_UNIFORMS,
+                    handle, index, length, size, type, name);
 }
diff --git a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp
index 1b08667..02817d4 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp
@@ -140,6 +140,22 @@
     }
 }
 
+//
+// Change all function entries in the table with the non-mangled name
+// to be related to the provided built-in extension. This is a low
+// performance operation, and only intended for symbol tables that
+// live across a large number of compiles.
+//
+void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
+{
+    for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
+        if (it->second->isFunction()) {
+            TFunction* function = static_cast<TFunction*>(it->second);
+            if (function->getName() == name)
+                function->relateToExtension(ext);
+        }
+    }
+}
 
 TSymbol::TSymbol(const TSymbol& copyOf)
 {
diff --git a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h
index b1a80b5..38bc657 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h
@@ -94,7 +94,10 @@
 
     void shareConstPointer( ConstantUnion *constArray)
     {
-        delete unionArray;
+        if (unionArray == constArray)
+            return;
+
+        delete[] unionArray;
         unionArray = constArray;  
     }
     TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
@@ -156,14 +159,18 @@
 
     const TString& getMangledName() const { return mangledName; }
     const TType& getReturnType() const { return returnType; }
+
     void relateToOperator(TOperator o) { op = o; }
     TOperator getBuiltInOp() const { return op; }
+
+    void relateToExtension(const TString& ext) { extension = ext; }
+    const TString& getExtension() const { return extension; }
+
     void setDefined() { defined = true; }
     bool isDefined() { return defined; }
 
-    int getParamCount() const { return static_cast<int>(parameters.size()); }    
-    TParameter& operator [](int i)       { return parameters[i]; }
-    const TParameter& operator [](int i) const { return parameters[i]; }
+    int getParamCount() const { return static_cast<int>(parameters.size()); }  
+    const TParameter& getParam(int i) const { return parameters[i]; }
 
     virtual void dump(TInfoSink &infoSink) const;
     TFunction(const TFunction&, TStructureMap& remapper);
@@ -175,6 +182,7 @@
     TType returnType;
     TString mangledName;
     TOperator op;
+    TString extension;
     bool defined;
 };
 
@@ -221,6 +229,7 @@
     }
 
     void relateToOperator(const char* name, TOperator op);
+    void relateToExtension(const char* name, const TString& ext);
     void dump(TInfoSink &infoSink) const;
     TSymbolTableLevel* clone(TStructureMap& remapper);
 
@@ -289,8 +298,16 @@
         return symbol;
     }
 
-    TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 2); return table[1]; }
-    void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
+    TSymbolTableLevel* getGlobalLevel() {
+        assert(table.size() >= 2);
+        return table[1];
+    }
+    void relateToOperator(const char* name, TOperator op) {
+        table[0]->relateToOperator(name, op);
+    }
+    void relateToExtension(const char* name, const TString& ext) {
+        table[0]->relateToExtension(name, ext);
+    }
     int getMaxSymbolId() { return uniqueId; }
     void dump(TInfoSink &infoSink) const;
     void copyTable(const TSymbolTable& copyOf);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp
index 7b8d903..7a63ae1 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp
@@ -7,14 +7,31 @@
 #include "compiler/TranslatorGLSL.h"
 
 #include "compiler/OutputGLSL.h"
+#include "compiler/VersionGLSL.h"
 
-TranslatorGLSL::TranslatorGLSL(EShLanguage lang, EShSpec spec)
-    : TCompiler(lang, spec) {
+static void writeVersion(ShShaderType type, TIntermNode* root,
+                         TInfoSinkBase& sink) {
+    TVersionGLSL versionGLSL(type);
+    root->traverse(&versionGLSL);
+    int version = versionGLSL.getVersion();
+    // We need to write version directive only if it is greater than 110.
+    // If there is no version directive in the shader, 110 is implied.
+    if (version > 110) {
+        sink << "#version " << version << "\n";
+    }
 }
 
-bool TranslatorGLSL::compile(TIntermNode* root) {
-    TOutputGLSL outputGLSL(infoSink.obj);
-    root->traverse(&outputGLSL);
+TranslatorGLSL::TranslatorGLSL(ShShaderType type, ShShaderSpec spec)
+    : TCompiler(type, spec) {
+}
 
-    return true;
+void TranslatorGLSL::translate(TIntermNode* root) {
+    TInfoSinkBase& sink = getInfoSink().obj;
+
+    // Write GLSL version.
+    writeVersion(getShaderType(), root, sink);
+
+    // Write translated shader.
+    TOutputGLSL outputGLSL(sink);
+    root->traverse(&outputGLSL);
 }
diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h
index 973e39a..c2ce06d 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h
@@ -11,8 +11,10 @@
 
 class TranslatorGLSL : public TCompiler {
 public:
-    TranslatorGLSL(EShLanguage lang, EShSpec spec);
-    virtual bool compile(TIntermNode* root);
+    TranslatorGLSL(ShShaderType type, ShShaderSpec spec);
+
+protected:
+    virtual void translate(TIntermNode* root);
 };
 
 #endif  // COMPILER_TRANSLATORGLSL_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp
index 3a1e52d..96d7f10 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp
@@ -8,17 +8,15 @@
 
 #include "compiler/OutputHLSL.h"
 
-TranslatorHLSL::TranslatorHLSL(EShLanguage lang, EShSpec spec)
-    : TCompiler(lang, spec)
+TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec)
+    : TCompiler(type, spec)
 {
 }
 
-bool TranslatorHLSL::compile(TIntermNode *root)
+void TranslatorHLSL::translate(TIntermNode *root)
 {
     TParseContext& parseContext = *GetGlobalParseContext();
     sh::OutputHLSL outputHLSL(parseContext);
 
     outputHLSL.output();
-    
-    return true;
 }
diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h
index 38a5f0c..c3f672b 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h
@@ -11,8 +11,10 @@
 
 class TranslatorHLSL : public TCompiler {
 public:
-    TranslatorHLSL(EShLanguage lang, EShSpec spec);
-    virtual bool compile(TIntermNode* root);
+    TranslatorHLSL(ShShaderType type, ShShaderSpec spec);
+
+protected:
+    virtual void translate(TIntermNode* root);
 };
 
 #endif  // COMPILER_TRANSLATORHLSL_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Types.h b/Source/ThirdParty/ANGLE/src/compiler/Types.h
index 897b28f..d0fcc08 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Types.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/Types.h
@@ -85,12 +85,12 @@
     TType() {}
     TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
             type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
-            structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0)
     {
     }
     explicit TType(const TPublicType &p) :
             type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
-            structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+            maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0)
     {
         if (p.userDef) {
             structure = p.userDef->getStruct();
@@ -99,7 +99,7 @@
     }
     TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
             type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
-            structure(userDef), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
+            maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), fieldName(0), mangled(0)
     {
         typeName = NewPoolTString(n.c_str());
     }
diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp
index 20035fe..a36c393 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp
@@ -3,6 +3,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
+// UnfoldSelect is an AST traverser to output the select operator ?: as if-else statements
+//
 
 #include "compiler/UnfoldSelect.h"
 
@@ -44,7 +46,7 @@
                "}\n"
                "else\n"
                "{\n";
-        node->getCondition()->traverse(this);
+        node->getFalseBlock()->traverse(this);
         out << "    t" << i << " = ";
         node->getFalseBlock()->traverse(mOutputHLSL);
         out << ";\n"
diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h
index 68b2e8a..de296e4 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h
@@ -3,6 +3,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
+// UnfoldSelect is an AST traverser to output the select operator ?: as if-else statements
+//
 
 #ifndef COMPILER_UNFOLDSELECT_H_
 #define COMPILER_UNFOLDSELECT_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp
new file mode 100644
index 0000000..886f693
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp
@@ -0,0 +1,468 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/ValidateLimitations.h"
+#include "compiler/InfoSink.h"
+#include "compiler/ParseHelper.h"
+
+namespace {
+bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) {
+    for (TLoopStack::const_iterator i = stack.begin(); i != stack.end(); ++i) {
+        if (i->index.id == symbol->getId())
+            return true;
+    }
+    return false;
+}
+
+// Traverses a node to check if it represents a constant index expression.
+// Definition:
+// constant-index-expressions are a superset of constant-expressions.
+// Constant-index-expressions can include loop indices as defined in
+// GLSL ES 1.0 spec, Appendix A, section 4.
+// The following are constant-index-expressions:
+// - Constant expressions
+// - Loop indices as defined in section 4
+// - Expressions composed of both of the above
+class ValidateConstIndexExpr : public TIntermTraverser {
+public:
+    ValidateConstIndexExpr(const TLoopStack& stack)
+        : mValid(true), mLoopStack(stack) {}
+
+    // Returns true if the parsed node represents a constant index expression.
+    bool isValid() const { return mValid; }
+
+    virtual void visitSymbol(TIntermSymbol* symbol) {
+        // Only constants and loop indices are allowed in a
+        // constant index expression.
+        if (mValid) {
+            mValid = (symbol->getQualifier() == EvqConst) ||
+                     IsLoopIndex(symbol, mLoopStack);
+        }
+    }
+    virtual void visitConstantUnion(TIntermConstantUnion*) {}
+    virtual bool visitBinary(Visit, TIntermBinary*) { return true; }
+    virtual bool visitUnary(Visit, TIntermUnary*) { return true; }
+    virtual bool visitSelection(Visit, TIntermSelection*) { return true; }
+    virtual bool visitAggregate(Visit, TIntermAggregate*) { return true; }
+    virtual bool visitLoop(Visit, TIntermLoop*) { return true; }
+    virtual bool visitBranch(Visit, TIntermBranch*) { return true; }
+
+private:
+    bool mValid;
+    const TLoopStack& mLoopStack;
+};
+}  // namespace
+
+ValidateLimitations::ValidateLimitations(ShShaderType shaderType,
+                                         TInfoSinkBase& sink)
+    : mShaderType(shaderType),
+      mSink(sink),
+      mNumErrors(0)
+{
+}
+
+void ValidateLimitations::visitSymbol(TIntermSymbol*)
+{
+}
+
+void ValidateLimitations::visitConstantUnion(TIntermConstantUnion*)
+{
+}
+
+bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node)
+{
+    // Check if loop index is modified in the loop body.
+    validateOperation(node, node->getLeft());
+
+    // Check indexing.
+    switch (node->getOp()) {
+      case EOpIndexDirect:
+      case EOpIndexIndirect:
+        validateIndexing(node);
+        break;
+      default: break;
+    }
+    return true;
+}
+
+bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node)
+{
+    // Check if loop index is modified in the loop body.
+    validateOperation(node, node->getOperand());
+
+    return true;
+}
+
+bool ValidateLimitations::visitSelection(Visit, TIntermSelection*)
+{
+    return true;
+}
+
+bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node)
+{
+    switch (node->getOp()) {
+      case EOpFunctionCall:
+        validateFunctionCall(node);
+        break;
+      default:
+        break;
+    }
+    return true;
+}
+
+bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node)
+{
+    if (!validateLoopType(node))
+        return false;
+
+    TLoopInfo info;
+    memset(&info, 0, sizeof(TLoopInfo));
+    if (!validateForLoopHeader(node, &info))
+        return false;
+
+    TIntermNode* body = node->getBody();
+    if (body != NULL) {
+        mLoopStack.push_back(info);
+        body->traverse(this);
+        mLoopStack.pop_back();
+    }
+
+    // The loop is fully processed - no need to visit children.
+    return false;
+}
+
+bool ValidateLimitations::visitBranch(Visit, TIntermBranch*)
+{
+    return true;
+}
+
+void ValidateLimitations::error(TSourceLoc loc,
+                                const char *reason, const char* token)
+{
+    mSink.prefix(EPrefixError);
+    mSink.location(loc);
+    mSink << "'" << token << "' : " << reason << "\n";
+    ++mNumErrors;
+}
+
+bool ValidateLimitations::withinLoopBody() const
+{
+    return !mLoopStack.empty();
+}
+
+bool ValidateLimitations::isLoopIndex(const TIntermSymbol* symbol) const
+{
+    return IsLoopIndex(symbol, mLoopStack);
+}
+
+bool ValidateLimitations::validateLoopType(TIntermLoop* node) {
+    TLoopType type = node->getType();
+    if (type == ELoopFor)
+        return true;
+
+    // Reject while and do-while loops.
+    error(node->getLine(),
+          "This type of loop is not allowed",
+          type == ELoopWhile ? "while" : "do");
+    return false;
+}
+
+bool ValidateLimitations::validateForLoopHeader(TIntermLoop* node,
+                                                TLoopInfo* info)
+{
+    ASSERT(node->getType() == ELoopFor);
+
+    //
+    // The for statement has the form:
+    //    for ( init-declaration ; condition ; expression ) statement
+    //
+    if (!validateForLoopInit(node, info))
+        return false;
+    if (!validateForLoopCond(node, info))
+        return false;
+    if (!validateForLoopExpr(node, info))
+        return false;
+
+    return true;
+}
+
+bool ValidateLimitations::validateForLoopInit(TIntermLoop* node,
+                                              TLoopInfo* info)
+{
+    TIntermNode* init = node->getInit();
+    if (init == NULL) {
+        error(node->getLine(), "Missing init declaration", "for");
+        return false;
+    }
+
+    //
+    // init-declaration has the form:
+    //     type-specifier identifier = constant-expression
+    //
+    TIntermAggregate* decl = init->getAsAggregate();
+    if ((decl == NULL) || (decl->getOp() != EOpDeclaration)) {
+        error(init->getLine(), "Invalid init declaration", "for");
+        return false;
+    }
+    // To keep things simple do not allow declaration list.
+    TIntermSequence& declSeq = decl->getSequence();
+    if (declSeq.size() != 1) {
+        error(decl->getLine(), "Invalid init declaration", "for");
+        return false;
+    }
+    TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
+    if ((declInit == NULL) || (declInit->getOp() != EOpInitialize)) {
+        error(decl->getLine(), "Invalid init declaration", "for");
+        return false;
+    }
+    TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
+    if (symbol == NULL) {
+        error(declInit->getLine(), "Invalid init declaration", "for");
+        return false;
+    }
+    // The loop index has type int or float.
+    TBasicType type = symbol->getBasicType();
+    if ((type != EbtInt) && (type != EbtFloat)) {
+        error(symbol->getLine(),
+              "Invalid type for loop index", getBasicString(type));
+        return false;
+    }
+    // The loop index is initialized with constant expression.
+    if (!isConstExpr(declInit->getRight())) {
+        error(declInit->getLine(),
+              "Loop index cannot be initialized with non-constant expression",
+              symbol->getSymbol().c_str());
+        return false;
+    }
+
+    info->index.id = symbol->getId();
+    return true;
+}
+
+bool ValidateLimitations::validateForLoopCond(TIntermLoop* node,
+                                              TLoopInfo* info)
+{
+    TIntermNode* cond = node->getCondition();
+    if (cond == NULL) {
+        error(node->getLine(), "Missing condition", "for");
+        return false;
+    }
+    //
+    // condition has the form:
+    //     loop_index relational_operator constant_expression
+    //
+    TIntermBinary* binOp = cond->getAsBinaryNode();
+    if (binOp == NULL) {
+        error(node->getLine(), "Invalid condition", "for");
+        return false;
+    }
+    // Loop index should be to the left of relational operator.
+    TIntermSymbol* symbol = binOp->getLeft()->getAsSymbolNode();
+    if (symbol == NULL) {
+        error(binOp->getLine(), "Invalid condition", "for");
+        return false;
+    }
+    if (symbol->getId() != info->index.id) {
+        error(symbol->getLine(),
+              "Expected loop index", symbol->getSymbol().c_str());
+        return false;
+    }
+    // Relational operator is one of: > >= < <= == or !=.
+    switch (binOp->getOp()) {
+      case EOpEqual:
+      case EOpNotEqual:
+      case EOpLessThan:
+      case EOpGreaterThan:
+      case EOpLessThanEqual:
+      case EOpGreaterThanEqual:
+        break;
+      default:
+        error(binOp->getLine(),
+              "Invalid relational operator",
+              getOperatorString(binOp->getOp()));
+        break;
+    }
+    // Loop index must be compared with a constant.
+    if (!isConstExpr(binOp->getRight())) {
+        error(binOp->getLine(),
+              "Loop index cannot be compared with non-constant expression",
+              symbol->getSymbol().c_str());
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateLimitations::validateForLoopExpr(TIntermLoop* node,
+                                              TLoopInfo* info)
+{
+    TIntermNode* expr = node->getExpression();
+    if (expr == NULL) {
+        error(node->getLine(), "Missing expression", "for");
+        return false;
+    }
+
+    // for expression has one of the following forms:
+    //     loop_index++
+    //     loop_index--
+    //     loop_index += constant_expression
+    //     loop_index -= constant_expression
+    //     ++loop_index
+    //     --loop_index
+    // The last two forms are not specified in the spec, but I am assuming
+    // its an oversight.
+    TIntermUnary* unOp = expr->getAsUnaryNode();
+    TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode();
+
+    TOperator op = EOpNull;
+    TIntermSymbol* symbol = NULL;
+    if (unOp != NULL) {
+        op = unOp->getOp();
+        symbol = unOp->getOperand()->getAsSymbolNode();
+    } else if (binOp != NULL) {
+        op = binOp->getOp();
+        symbol = binOp->getLeft()->getAsSymbolNode();
+    }
+
+    // The operand must be loop index.
+    if (symbol == NULL) {
+        error(expr->getLine(), "Invalid expression", "for");
+        return false;
+    }
+    if (symbol->getId() != info->index.id) {
+        error(symbol->getLine(),
+              "Expected loop index", symbol->getSymbol().c_str());
+        return false;
+    }
+
+    // The operator is one of: ++ -- += -=.
+    switch (op) {
+        case EOpPostIncrement:
+        case EOpPostDecrement:
+        case EOpPreIncrement:
+        case EOpPreDecrement:
+            ASSERT((unOp != NULL) && (binOp == NULL));
+            break;
+        case EOpAddAssign:
+        case EOpSubAssign:
+            ASSERT((unOp == NULL) && (binOp != NULL));
+            break;
+        default:
+            error(expr->getLine(), "Invalid operator", getOperatorString(op));
+            return false;
+    }
+
+    // Loop index must be incremented/decremented with a constant.
+    if (binOp != NULL) {
+        if (!isConstExpr(binOp->getRight())) {
+            error(binOp->getLine(),
+                  "Loop index cannot be modified by non-constant expression",
+                  symbol->getSymbol().c_str());
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
+{
+    ASSERT(node->getOp() == EOpFunctionCall);
+
+    // If not within loop body, there is nothing to check.
+    if (!withinLoopBody())
+        return true;
+
+    // List of param indices for which loop indices are used as argument.
+    typedef std::vector<int> ParamIndex;
+    ParamIndex pIndex;
+    TIntermSequence& params = node->getSequence();
+    for (TIntermSequence::size_type i = 0; i < params.size(); ++i) {
+        TIntermSymbol* symbol = params[i]->getAsSymbolNode();
+        if (symbol && isLoopIndex(symbol))
+            pIndex.push_back(i);
+    }
+    // If none of the loop indices are used as arguments,
+    // there is nothing to check.
+    if (pIndex.empty())
+        return true;
+
+    bool valid = true;
+    TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
+    TSymbol* symbol = symbolTable.find(node->getName());
+    ASSERT(symbol && symbol->isFunction());
+    TFunction* function = static_cast<TFunction*>(symbol);
+    for (ParamIndex::const_iterator i = pIndex.begin();
+         i != pIndex.end(); ++i) {
+        const TParameter& param = function->getParam(*i);
+        TQualifier qual = param.type->getQualifier();
+        if ((qual == EvqOut) || (qual == EvqInOut)) {
+            error(params[*i]->getLine(),
+                  "Loop index cannot be used as argument to a function out or inout parameter",
+                  params[*i]->getAsSymbolNode()->getSymbol().c_str());
+            valid = false;
+        }
+    }
+
+    return valid;
+}
+
+bool ValidateLimitations::validateOperation(TIntermOperator* node,
+                                            TIntermNode* operand) {
+    // Check if loop index is modified in the loop body.
+    if (!withinLoopBody() || !node->modifiesState())
+        return true;
+
+    const TIntermSymbol* symbol = operand->getAsSymbolNode();
+    if (symbol && isLoopIndex(symbol)) {
+        error(node->getLine(),
+              "Loop index cannot be statically assigned to within the body of the loop",
+              symbol->getSymbol().c_str());
+    }
+    return true;
+}
+
+bool ValidateLimitations::isConstExpr(TIntermNode* node)
+{
+    ASSERT(node != NULL);
+    return node->getAsConstantUnion() != NULL;
+}
+
+bool ValidateLimitations::isConstIndexExpr(TIntermNode* node)
+{
+    ASSERT(node != NULL);
+
+    ValidateConstIndexExpr validate(mLoopStack);
+    node->traverse(&validate);
+    return validate.isValid();
+}
+
+bool ValidateLimitations::validateIndexing(TIntermBinary* node)
+{
+    ASSERT((node->getOp() == EOpIndexDirect) ||
+           (node->getOp() == EOpIndexIndirect));
+
+    bool valid = true;
+    TIntermTyped* index = node->getRight();
+    // The index expression must have integral type.
+    if (!index->isScalar() || (index->getBasicType() != EbtInt)) {
+        error(index->getLine(),
+              "Index expression must have integral type",
+              index->getCompleteString().c_str());
+        valid = false;
+    }
+    // The index expession must be a constant-index-expression unless
+    // the operand is a uniform in a vertex shader.
+    TIntermTyped* operand = node->getLeft();
+    bool skip = (mShaderType == SH_VERTEX_SHADER) &&
+                (operand->getQualifier() == EvqUniform);
+    if (!skip && !isConstIndexExpr(index)) {
+        error(index->getLine(), "Index expression must be constant", "[]");
+        valid = false;
+    }
+    return valid;
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h
new file mode 100644
index 0000000..a4f5a28
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h
@@ -0,0 +1,62 @@
+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/intermediate.h"
+
+class TInfoSinkBase;
+
+struct TLoopInfo {
+    struct TIndex {
+        int id;  // symbol id.
+    } index;
+};
+typedef TVector<TLoopInfo> TLoopStack;
+
+// Traverses intermediate tree to ensure that the shader does not exceed the
+// minimum functionality mandated in GLSL 1.0 spec, Appendix A.
+class ValidateLimitations : public TIntermTraverser {
+public:
+    ValidateLimitations(ShShaderType shaderType, TInfoSinkBase& sink);
+
+    int numErrors() const { return mNumErrors; }
+
+    virtual void visitSymbol(TIntermSymbol*);
+    virtual void visitConstantUnion(TIntermConstantUnion*);
+    virtual bool visitBinary(Visit, TIntermBinary*);
+    virtual bool visitUnary(Visit, TIntermUnary*);
+    virtual bool visitSelection(Visit, TIntermSelection*);
+    virtual bool visitAggregate(Visit, TIntermAggregate*);
+    virtual bool visitLoop(Visit, TIntermLoop*);
+    virtual bool visitBranch(Visit, TIntermBranch*);
+
+private:
+    void error(TSourceLoc loc, const char *reason, const char* token);
+
+    bool withinLoopBody() const;
+    bool isLoopIndex(const TIntermSymbol* symbol) const;
+    bool validateLoopType(TIntermLoop* node);
+    bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info);
+    bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info);
+    bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info);
+    bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info);
+    // Returns true if none of the loop indices is used as the argument to
+    // the given function out or inout parameter.
+    bool validateFunctionCall(TIntermAggregate* node);
+    bool validateOperation(TIntermOperator* node, TIntermNode* operand);
+
+    // Returns true if indexing does not exceed the minimum functionality
+    // mandated in GLSL 1.0 spec, Appendix A, Section 5.
+    bool isConstExpr(TIntermNode* node);
+    bool isConstIndexExpr(TIntermNode* node);
+    bool validateIndexing(TIntermBinary* node);
+
+    ShShaderType mShaderType;
+    TInfoSinkBase& mSink;
+    int mNumErrors;
+    TLoopStack mLoopStack;
+};
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp
new file mode 100644
index 0000000..ad2e08f
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp
@@ -0,0 +1,210 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/VariableInfo.h"
+
+static TString arrayBrackets(int index)
+{
+    TStringStream stream;
+    stream << "[" << index << "]";
+    return stream.str();
+}
+
+// Returns the data type for an attribute or uniform.
+static ShDataType getVariableDataType(const TType& type)
+{
+    switch (type.getBasicType()) {
+      case EbtFloat:
+          if (type.isMatrix()) {
+              switch (type.getNominalSize()) {
+                case 2: return SH_FLOAT_MAT2;
+                case 3: return SH_FLOAT_MAT3;
+                case 4: return SH_FLOAT_MAT4;
+                default: UNREACHABLE();
+              }
+          } else if (type.isVector()) {
+              switch (type.getNominalSize()) {
+                case 2: return SH_FLOAT_VEC2;
+                case 3: return SH_FLOAT_VEC3;
+                case 4: return SH_FLOAT_VEC4;
+                default: UNREACHABLE();
+              }
+          } else {
+              return SH_FLOAT;
+          }
+      case EbtInt:
+          if (type.isMatrix()) {
+              UNREACHABLE();
+          } else if (type.isVector()) {
+              switch (type.getNominalSize()) {
+                case 2: return SH_INT_VEC2;
+                case 3: return SH_INT_VEC3;
+                case 4: return SH_INT_VEC4;
+                default: UNREACHABLE();
+              }
+          } else {
+              return SH_INT;
+          }
+      case EbtBool:
+          if (type.isMatrix()) {
+              UNREACHABLE();
+          } else if (type.isVector()) {
+              switch (type.getNominalSize()) {
+                case 2: return SH_BOOL_VEC2;
+                case 3: return SH_BOOL_VEC3;
+                case 4: return SH_BOOL_VEC4;
+                default: UNREACHABLE();
+              }
+          } else {
+              return SH_BOOL;
+          }
+      case EbtSampler2D: return SH_SAMPLER_2D;
+      case EbtSamplerCube: return SH_SAMPLER_CUBE;
+      default: UNREACHABLE();
+    }
+    return SH_NONE;
+}
+
+static void getBuiltInVariableInfo(const TType& type,
+                                   const TString& name,
+                                   TVariableInfoList& infoList);
+static void getUserDefinedVariableInfo(const TType& type,
+                                       const TString& name,
+                                       TVariableInfoList& infoList);
+
+// Returns info for an attribute or uniform.
+static void getVariableInfo(const TType& type,
+                            const TString& name,
+                            TVariableInfoList& infoList)
+{
+    if (type.getBasicType() == EbtStruct) {
+        if (type.isArray()) {
+            for (int i = 0; i < type.getArraySize(); ++i) {
+                TString lname = name + arrayBrackets(i);
+                getUserDefinedVariableInfo(type, lname, infoList);
+            }
+        } else {
+            getUserDefinedVariableInfo(type, name, infoList);
+        }
+    } else {
+        getBuiltInVariableInfo(type, name, infoList);
+    }
+}
+
+void getBuiltInVariableInfo(const TType& type,
+                            const TString& name,
+                            TVariableInfoList& infoList)
+{
+    ASSERT(type.getBasicType() != EbtStruct);
+
+    TVariableInfo varInfo;
+    if (type.isArray()) {
+        varInfo.name = (name + "[0]").c_str();
+        varInfo.size = type.getArraySize();
+    } else {
+        varInfo.name = name.c_str();
+        varInfo.size = 1;
+    }
+    varInfo.type = getVariableDataType(type);
+    infoList.push_back(varInfo);
+}
+
+void getUserDefinedVariableInfo(const TType& type,
+                                const TString& name,
+                                TVariableInfoList& infoList)
+{
+    ASSERT(type.getBasicType() == EbtStruct);
+
+    TString lname = name + ".";
+    const TTypeList* structure = type.getStruct();
+    for (size_t i = 0; i < structure->size(); ++i) {
+        const TType* fieldType = (*structure)[i].type;
+        getVariableInfo(*fieldType,
+                        lname + fieldType->getFieldName(),
+                        infoList);
+    }
+}
+
+CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
+                                               TVariableInfoList& uniforms)
+    : mAttribs(attribs),
+      mUniforms(uniforms)
+{
+}
+
+// We are only interested in attribute and uniform variable declaration.
+void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
+{
+}
+
+void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
+{
+}
+
+bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
+{
+    return false;
+}
+
+bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
+{
+    return false;
+}
+
+bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
+{
+    return false;
+}
+
+bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
+{
+    bool visitChildren = false;
+
+    switch (node->getOp())
+    {
+    case EOpSequence:
+        // We need to visit sequence children to get to variable declarations.
+        visitChildren = true;
+        break;
+    case EOpDeclaration: {
+        const TIntermSequence& sequence = node->getSequence();
+        TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
+        if (qualifier == EvqAttribute || qualifier == EvqUniform)
+        {
+            TVariableInfoList& infoList = qualifier == EvqAttribute ?
+                mAttribs : mUniforms;
+            for (TIntermSequence::const_iterator i = sequence.begin();
+                 i != sequence.end(); ++i)
+            {
+                const TIntermSymbol* variable = (*i)->getAsSymbolNode();
+                // The only case in which the sequence will not contain a
+                // TIntermSymbol node is initialization. It will contain a
+                // TInterBinary node in that case. Since attributes and unifroms
+                // cannot be initialized in a shader, we must have only
+                // TIntermSymbol nodes in the sequence.
+                ASSERT(variable != NULL);
+                getVariableInfo(variable->getType(), variable->getSymbol(),
+                                infoList);
+            }
+        }
+        break;
+    }
+    default: break;
+    }
+
+    return visitChildren;
+}
+
+bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
+{
+    return false;
+}
+
+bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
+{
+    return false;
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h
new file mode 100644
index 0000000..15a5c57
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/intermediate.h"
+
+// Provides information about a variable.
+// It is currently being used to store info about active attribs and uniforms.
+struct TVariableInfo {
+    TPersistString name;
+    ShDataType type;
+    int size;
+};
+typedef std::vector<TVariableInfo> TVariableInfoList;
+
+// Traverses intermediate tree to collect all attributes and uniforms.
+class CollectAttribsUniforms : public TIntermTraverser {
+public:
+    CollectAttribsUniforms(TVariableInfoList& attribs,
+                           TVariableInfoList& uniforms);
+
+    virtual void visitSymbol(TIntermSymbol*);
+    virtual void visitConstantUnion(TIntermConstantUnion*);
+    virtual bool visitBinary(Visit, TIntermBinary*);
+    virtual bool visitUnary(Visit, TIntermUnary*);
+    virtual bool visitSelection(Visit, TIntermSelection*);
+    virtual bool visitAggregate(Visit, TIntermAggregate*);
+    virtual bool visitLoop(Visit, TIntermLoop*);
+    virtual bool visitBranch(Visit, TIntermBranch*);
+
+private:
+    TVariableInfoList& mAttribs;
+    TVariableInfoList& mUniforms;
+};
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp
new file mode 100644
index 0000000..3f87820
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp
@@ -0,0 +1,108 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/VersionGLSL.h"
+
+static const int GLSL_VERSION_110 = 110;
+static const int GLSL_VERSION_120 = 120;
+
+// We need to scan for two things:
+// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
+//    but only at the global scope.
+// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
+//    but inside any scope.
+// So we need to scan the entire fragment shader but only the global scope
+// of vertex shader.
+//
+// TODO(alokp): The following two cases of invariant decalaration get lost
+// during parsing - they do not get carried over to the intermediate tree.
+// Handle these cases:
+// 1. When a pragma is used to force all output variables to be invariant:
+//    - #pragma STDGL invariant(all)
+// 2. When a previously decalared or built-in variable is marked invariant:
+//    - invariant gl_Position;
+//    - varying vec3 color; invariant color;
+//
+TVersionGLSL::TVersionGLSL(ShShaderType type)
+    : mShaderType(type),
+      mVersion(GLSL_VERSION_110)
+{
+}
+
+void TVersionGLSL::visitSymbol(TIntermSymbol* node)
+{
+    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+
+    if (node->getSymbol() == "gl_PointCoord")
+        updateVersion(GLSL_VERSION_120);
+}
+
+void TVersionGLSL::visitConstantUnion(TIntermConstantUnion*)
+{
+    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+}
+
+bool TVersionGLSL::visitBinary(Visit, TIntermBinary*)
+{
+    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+    return true;
+}
+
+bool TVersionGLSL::visitUnary(Visit, TIntermUnary*)
+{
+    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+    return true;
+}
+
+bool TVersionGLSL::visitSelection(Visit, TIntermSelection*)
+{
+    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+    return true;
+}
+
+bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node)
+{
+    // We need to scan the entire fragment shader but only the global scope
+    // of vertex shader.
+    bool visitChildren = mShaderType == SH_FRAGMENT_SHADER ? true : false;
+
+    switch (node->getOp()) {
+      case EOpSequence:
+        // We need to visit sequence children to get to global or inner scope.
+        visitChildren = true;
+        break;
+      case EOpDeclaration: {
+        const TIntermSequence& sequence = node->getSequence();
+        TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
+        if ((qualifier == EvqInvariantVaryingIn) ||
+            (qualifier == EvqInvariantVaryingOut)) {
+            updateVersion(GLSL_VERSION_120);
+        }
+        break;
+      }
+      default: break;
+    }
+
+    return visitChildren;
+}
+
+bool TVersionGLSL::visitLoop(Visit, TIntermLoop*)
+{
+    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+    return true;
+}
+
+bool TVersionGLSL::visitBranch(Visit, TIntermBranch*)
+{
+    ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+    return true;
+}
+
+void TVersionGLSL::updateVersion(int version)
+{
+    mVersion = std::max(version, mVersion);
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h
new file mode 100644
index 0000000..64d002b
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h
@@ -0,0 +1,50 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_VERSIONGLSL_H_
+#define COMPILER_VERSIONGLSL_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/intermediate.h"
+
+// Traverses the intermediate tree to return the minimum GLSL version
+// required to legally access all built-in features used in the shader.
+// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
+//   - #version and #extension to declare version and extensions.
+//   - built-in functions refract, exp, and log.
+//   - updated step() to compare x < edge instead of x <= edge.
+// GLSL 1.2 which is mandated by OpenGL 2.1 provides:
+//   - many changes to reduce differences when compared to the ES specification.
+//   - invariant keyword and its support.
+//   - c++ style name hiding rules.
+//   - built-in variable gl_PointCoord for fragment shaders.
+//
+class TVersionGLSL : public TIntermTraverser {
+public:
+    TVersionGLSL(ShShaderType type);
+
+    // Returns 120 if "invariant" keyword or "gl_PointCoord" is used
+    // in the shader. Else 110 is returned.
+    int getVersion() { return mVersion; }
+
+    virtual void visitSymbol(TIntermSymbol*);
+    virtual void visitConstantUnion(TIntermConstantUnion*);
+    virtual bool visitBinary(Visit, TIntermBinary*);
+    virtual bool visitUnary(Visit, TIntermUnary*);
+    virtual bool visitSelection(Visit, TIntermSelection*);
+    virtual bool visitAggregate(Visit, TIntermAggregate*);
+    virtual bool visitLoop(Visit, TIntermLoop*);
+    virtual bool visitBranch(Visit, TIntermBranch*);
+
+protected:
+    void updateVersion(int version);
+
+private:
+    ShShaderType mShaderType;
+    int mVersion;
+};
+
+#endif  // COMPILER_VERSIONGLSL_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_lexer.sh b/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_lexer.sh
new file mode 100644
index 0000000..268479d
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_lexer.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generates GLSL ES lexer - glslang_lex.cpp
+
+script_dir=$(dirname $0)
+input_file=$script_dir/glslang.l
+output_file=$script_dir/glslang_lex.cpp
+flex --noline --nounistd --outfile=$output_file $input_file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_parser.sh b/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_parser.sh
new file mode 100644
index 0000000..889f5c0
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_parser.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generates GLSL ES parser - glslang_tab.h and glslang_tab.cpp
+
+script_dir=$(dirname $0)
+input_file=$script_dir/glslang.y
+output_header=$script_dir/glslang_tab.h
+output_source=$script_dir/glslang_tab.cpp
+bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.h b/Source/ThirdParty/ANGLE/src/compiler/glslang.h
new file mode 100644
index 0000000..26f1457
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.h
@@ -0,0 +1,16 @@
+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+struct TParseContext;
+extern int glslang_initialize(TParseContext* context);
+extern int glslang_finalize(TParseContext* context);
+
+extern void glslang_scan(int count,
+                         const char* const string[],
+                         const int length[],
+                         TParseContext* context);
+extern int glslang_parse(TParseContext* context);
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.l b/Source/ThirdParty/ANGLE/src/compiler/glslang.l
index 02c226f..5a7c5d5 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/glslang.l
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.l
@@ -4,34 +4,29 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-*/
-/* Based on
-ANSI C grammar, Lex specification
 
-In 1985, Jeff Lee published this Lex specification together with a Yacc 
-grammar for the April 30, 1985 ANSI C draft.  Tom Stockfisch reposted 
-both to net.sources in 1987; that original, as mentioned in the answer 
-to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net, 
-file usenet/net.sources/ansi.c.grammar.Z. 
+This file contains the Lex specification for GLSL ES.
+Based on ANSI C grammar, Lex specification:
+http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
 
-I intend to keep this version as close to the current C Standard grammar 
-as possible; please let me know if you discover discrepancies. 
-
-Jutta Degener, 1995 
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_lexer.sh,
+WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
 */
 
-D           [0-9]
-L           [a-zA-Z_]
-H           [a-fA-F0-9]
-E           [Ee][+-]?{D}+
-O           [0-7]
+%top{
+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
 
-%option nounput 
+// This file is auto-generated by generate_glslang_lexer.sh. DO NOT EDIT!
+}
+
 %{
-#include <stdio.h>
-#include <stdlib.h>
-
+#include "compiler/glslang.h"
 #include "compiler/ParseHelper.h"
+#include "compiler/util.h"
 #include "glslang_tab.h"
 
 /* windows only pragma */
@@ -39,407 +34,304 @@
 #pragma warning(disable : 4102)
 #endif
 
-int yy_input(char* buf, int max_size);
+#define YY_USER_ACTION yylval->lex.line = yylineno;
+#define YY_INPUT(buf, result, max_size) \
+    result = string_input(buf, max_size, yyscanner);
 
-extern int yyparse(void*);
-#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
-#define parseContext (*((TParseContext*)(parseContextLocal)))
- 
-#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size))
-
+static int string_input(char* buf, int max_size, yyscan_t yyscanner);
+static int check_type(yyscan_t yyscanner);
+static int reserved_word(yyscan_t yyscanner);
 %}
 
-/*
-TODO(alokp): yylineno is only here to support old flex.exe in compiler/tools.
-Remove it when we can exclusively use the newer version.
-*/
-%option yylineno
+%option noyywrap nounput never-interactive
+%option yylineno reentrant bison-bridge
+%option stack
+%option extra-type="TParseContext*"
+%x COMMENT FIELDS
 
-%option noyywrap
-%option never-interactive
-%x FIELDS
-
+D           [0-9]
+L           [a-zA-Z_]
+H           [a-fA-F0-9]
+E           [Ee][+-]?{D}+
+O           [0-7]
 
 %%
-<*>"//"[^\n]*"\n"     { /* ?? carriage and/or line-feed? */ };
 
-"invariant"    {  pyylval->lex.line = yylineno; return(INVARIANT); }
-"highp"        {  pyylval->lex.line = yylineno; return(HIGH_PRECISION); }
-"mediump"      {  pyylval->lex.line = yylineno; return(MEDIUM_PRECISION); }
-"lowp"         {  pyylval->lex.line = yylineno; return(LOW_PRECISION); }
-"precision"    {  pyylval->lex.line = yylineno; return(PRECISION); }
+%{
+    TParseContext* context = yyextra;
+%}
 
-"attribute"    {  pyylval->lex.line = yylineno; return(ATTRIBUTE); }
-"const"        {  pyylval->lex.line = yylineno; return(CONST_QUAL); }
-"uniform"      {  pyylval->lex.line = yylineno; return(UNIFORM); }
-"varying"      {  pyylval->lex.line = yylineno; return(VARYING); }
+    /* Single-line comments */
+"//"[^\n]* ;
 
-"break"        {  pyylval->lex.line = yylineno; return(BREAK); }
-"continue"     {  pyylval->lex.line = yylineno; return(CONTINUE); }
-"do"           {  pyylval->lex.line = yylineno; return(DO); }
-"for"          {  pyylval->lex.line = yylineno; return(FOR); }
-"while"        {  pyylval->lex.line = yylineno; return(WHILE); }
+    /* Multi-line comments */
+"/*"           { yy_push_state(COMMENT, yyscanner); }
+<COMMENT>. |
+<COMMENT>\n ;
+<COMMENT>"*/"  { yy_pop_state(yyscanner); }
 
-"if"           {  pyylval->lex.line = yylineno; return(IF); }
-"else"         {  pyylval->lex.line = yylineno; return(ELSE); }
+"invariant"    { return(INVARIANT); }
+"highp"        { return(HIGH_PRECISION); }
+"mediump"      { return(MEDIUM_PRECISION); }
+"lowp"         { return(LOW_PRECISION); }
+"precision"    { return(PRECISION); }
 
-"in"           {  pyylval->lex.line = yylineno; return(IN_QUAL); }
-"out"          {  pyylval->lex.line = yylineno; return(OUT_QUAL); }
-"inout"        {  pyylval->lex.line = yylineno; return(INOUT_QUAL); }
+"attribute"    { return(ATTRIBUTE); }
+"const"        { return(CONST_QUAL); }
+"uniform"      { return(UNIFORM); }
+"varying"      { return(VARYING); }
 
-"float"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); }
-"int"          {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); }
-"void"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); }
-"bool"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
-"true"         {  pyylval->lex.line = yylineno; pyylval->lex.b = true;  return(BOOLCONSTANT); }
-"false"        {  pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
+"break"        { return(BREAK); }
+"continue"     { return(CONTINUE); }
+"do"           { return(DO); }
+"for"          { return(FOR); }
+"while"        { return(WHILE); }
 
-"discard"      {  pyylval->lex.line = yylineno; return(DISCARD); }
-"return"       {  pyylval->lex.line = yylineno; return(RETURN); }
+"if"           { return(IF); }
+"else"         { return(ELSE); }
 
-"mat2"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
-"mat3"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); }
-"mat4"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); }
+"in"           { return(IN_QUAL); }
+"out"          { return(OUT_QUAL); }
+"inout"        { return(INOUT_QUAL); }
 
-"vec2"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); }
-"vec3"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
-"vec4"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); }
-"ivec2"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
-"ivec3"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
-"ivec4"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); }
-"bvec2"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); }
-"bvec3"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
-"bvec4"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
+"float"        { context->lexAfterType = true; return(FLOAT_TYPE); }
+"int"          { context->lexAfterType = true; return(INT_TYPE); }
+"void"         { context->lexAfterType = true; return(VOID_TYPE); }
+"bool"         { context->lexAfterType = true; return(BOOL_TYPE); }
+"true"         { yylval->lex.b = true;  return(BOOLCONSTANT); }
+"false"        { yylval->lex.b = false; return(BOOLCONSTANT); }
 
-"sampler2D"       {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; }
-"samplerCube"     {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; }
+"discard"      { return(DISCARD); }
+"return"       { return(RETURN); }
 
-"struct"       {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(STRUCT); }
+"mat2"         { context->lexAfterType = true; return(MATRIX2); }
+"mat3"         { context->lexAfterType = true; return(MATRIX3); }
+"mat4"         { context->lexAfterType = true; return(MATRIX4); }
 
-"asm"          {  PaReservedWord(); return 0; }
+"vec2"         { context->lexAfterType = true; return (VEC2); }
+"vec3"         { context->lexAfterType = true; return (VEC3); }
+"vec4"         { context->lexAfterType = true; return (VEC4); }
+"ivec2"        { context->lexAfterType = true; return (IVEC2); }
+"ivec3"        { context->lexAfterType = true; return (IVEC3); }
+"ivec4"        { context->lexAfterType = true; return (IVEC4); }
+"bvec2"        { context->lexAfterType = true; return (BVEC2); }
+"bvec3"        { context->lexAfterType = true; return (BVEC3); }
+"bvec4"        { context->lexAfterType = true; return (BVEC4); }
 
-"class"        {  PaReservedWord(); return 0; }
-"union"        {  PaReservedWord(); return 0; }
-"enum"         {  PaReservedWord(); return 0; }
-"typedef"      {  PaReservedWord(); return 0; }
-"template"     {  PaReservedWord(); return 0; }
-"this"         {  PaReservedWord(); return 0; }
-"packed"       {  PaReservedWord(); return 0; }
+"sampler2D"       { context->lexAfterType = true; return SAMPLER2D; }
+"samplerCube"     { context->lexAfterType = true; return SAMPLERCUBE; }
 
-"goto"         {  PaReservedWord(); return 0; }
-"switch"       {  PaReservedWord(); return 0; }
-"default"      {  PaReservedWord(); return 0; }
+"struct"       { context->lexAfterType = true; return(STRUCT); }
 
-"inline"       {  PaReservedWord(); return 0; }
-"noinline"     {  PaReservedWord(); return 0; }
-"volatile"     {  PaReservedWord(); return 0; }
-"public"       {  PaReservedWord(); return 0; }
-"static"       {  PaReservedWord(); return 0; }
-"extern"       {  PaReservedWord(); return 0; }
-"external"     {  PaReservedWord(); return 0; }
-"interface"    {  PaReservedWord(); return 0; }
+"asm"          { return reserved_word(yyscanner); }
 
-"long"         {  PaReservedWord(); return 0; }
-"short"        {  PaReservedWord(); return 0; }
-"double"       {  PaReservedWord(); return 0; }
-"half"         {  PaReservedWord(); return 0; }
-"fixed"        {  PaReservedWord(); return 0; }
-"unsigned"     {  PaReservedWord(); return 0; }
+"class"        { return reserved_word(yyscanner); }
+"union"        { return reserved_word(yyscanner); }
+"enum"         { return reserved_word(yyscanner); }
+"typedef"      { return reserved_word(yyscanner); }
+"template"     { return reserved_word(yyscanner); }
+"this"         { return reserved_word(yyscanner); }
+"packed"       { return reserved_word(yyscanner); }
 
-"input"        {  PaReservedWord(); return 0; }
-"output"       {  PaReservedWord(); return 0; }
+"goto"         { return reserved_word(yyscanner); }
+"switch"       { return reserved_word(yyscanner); }
+"default"      { return reserved_word(yyscanner); }
 
-"hvec2"        {  PaReservedWord(); return 0; }
-"hvec3"        {  PaReservedWord(); return 0; }
-"hvec4"        {  PaReservedWord(); return 0; }
-"fvec2"        {  PaReservedWord(); return 0; }
-"fvec3"        {  PaReservedWord(); return 0; }
-"fvec4"        {  PaReservedWord(); return 0; }
-"dvec2"        {  PaReservedWord(); return 0; }
-"dvec3"        {  PaReservedWord(); return 0; }
-"dvec4"        {  PaReservedWord(); return 0; }
+"inline"       { return reserved_word(yyscanner); }
+"noinline"     { return reserved_word(yyscanner); }
+"volatile"     { return reserved_word(yyscanner); }
+"public"       { return reserved_word(yyscanner); }
+"static"       { return reserved_word(yyscanner); }
+"extern"       { return reserved_word(yyscanner); }
+"external"     { return reserved_word(yyscanner); }
+"interface"    { return reserved_word(yyscanner); }
 
-"sizeof"       {  PaReservedWord(); return 0; }
-"cast"         {  PaReservedWord(); return 0; }
+"long"         { return reserved_word(yyscanner); }
+"short"        { return reserved_word(yyscanner); }
+"double"       { return reserved_word(yyscanner); }
+"half"         { return reserved_word(yyscanner); }
+"fixed"        { return reserved_word(yyscanner); }
+"unsigned"     { return reserved_word(yyscanner); }
 
-"namespace"    {  PaReservedWord(); return 0; }
-"using"        {  PaReservedWord(); return 0; }
+"input"        { return reserved_word(yyscanner); }
+"output"       { return reserved_word(yyscanner); }
 
-{L}({L}|{D})*       {  
-   pyylval->lex.line = yylineno; 
-   pyylval->lex.string = NewPoolTString(yytext); 
-   return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol); 
+"hvec2"        { return reserved_word(yyscanner); }
+"hvec3"        { return reserved_word(yyscanner); }
+"hvec4"        { return reserved_word(yyscanner); }
+"fvec2"        { return reserved_word(yyscanner); }
+"fvec3"        { return reserved_word(yyscanner); }
+"fvec4"        { return reserved_word(yyscanner); }
+"dvec2"        { return reserved_word(yyscanner); }
+"dvec3"        { return reserved_word(yyscanner); }
+"dvec4"        { return reserved_word(yyscanner); }
+
+"sizeof"       { return reserved_word(yyscanner); }
+"cast"         { return reserved_word(yyscanner); }
+
+"namespace"    { return reserved_word(yyscanner); }
+"using"        { return reserved_word(yyscanner); }
+
+{L}({L}|{D})*       {
+   yylval->lex.string = NewPoolTString(yytext); 
+   return check_type(yyscanner);
 }
 
-0[xX]{H}+         { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-0{O}+             { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-0{D}+             { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
-{D}+              { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+0[xX]{H}+         { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+0{O}+             { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+0{D}+             { context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;}
+{D}+              { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
 
-{D}+{E}           { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-{D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-"."{D}+({E})?     { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
+{D}+{E}           { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+{D}+"."{D}*({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+"."{D}+({E})?     { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
 
-"/*"            {  int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }   
+"+="            {  return(ADD_ASSIGN); }
+"-="            {  return(SUB_ASSIGN); }
+"*="            {  return(MUL_ASSIGN); }
+"/="            {  return(DIV_ASSIGN); }
+"%="            {  return(MOD_ASSIGN); }
+"<<="           {  return(LEFT_ASSIGN); }
+">>="           {  return(RIGHT_ASSIGN); }
+"&="            {  return(AND_ASSIGN); }
+"^="            {  return(XOR_ASSIGN); }
+"|="            {  return(OR_ASSIGN); }
 
-"+="            {  pyylval->lex.line = yylineno; return(ADD_ASSIGN); }
-"-="            {  pyylval->lex.line = yylineno; return(SUB_ASSIGN); }
-"*="            {  pyylval->lex.line = yylineno; return(MUL_ASSIGN); }
-"/="            {  pyylval->lex.line = yylineno; return(DIV_ASSIGN); }
-"%="            {  pyylval->lex.line = yylineno; return(MOD_ASSIGN); }
-"<<="           {  pyylval->lex.line = yylineno; return(LEFT_ASSIGN); }
-">>="           {  pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); }
-"&="            {  pyylval->lex.line = yylineno; return(AND_ASSIGN); }
-"^="            {  pyylval->lex.line = yylineno; return(XOR_ASSIGN); }
-"|="            {  pyylval->lex.line = yylineno; return(OR_ASSIGN); }
-
-"++"            {  pyylval->lex.line = yylineno; return(INC_OP); }
-"--"            {  pyylval->lex.line = yylineno; return(DEC_OP); }
-"&&"            {  pyylval->lex.line = yylineno; return(AND_OP); }
-"||"            {  pyylval->lex.line = yylineno; return(OR_OP); }
-"^^"            {  pyylval->lex.line = yylineno; return(XOR_OP); }
-"<="            {  pyylval->lex.line = yylineno; return(LE_OP); }
-">="            {  pyylval->lex.line = yylineno; return(GE_OP); }
-"=="            {  pyylval->lex.line = yylineno; return(EQ_OP); }
-"!="            {  pyylval->lex.line = yylineno; return(NE_OP); }
-"<<"            {  pyylval->lex.line = yylineno; return(LEFT_OP); }
-">>"            {  pyylval->lex.line = yylineno; return(RIGHT_OP); }
-";"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); }
-("{"|"<%")      {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); }
-("}"|"%>")      {  pyylval->lex.line = yylineno; return(RIGHT_BRACE); }
-","         {  pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); }
-":"         {  pyylval->lex.line = yylineno; return(COLON); }
-"="         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); }
-"("         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); }
-")"         {  pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); }
-("["|"<:")      {  pyylval->lex.line = yylineno; return(LEFT_BRACKET); }
-("]"|":>")      {  pyylval->lex.line = yylineno; return(RIGHT_BRACKET); }
+"++"            {  return(INC_OP); }
+"--"            {  return(DEC_OP); }
+"&&"            {  return(AND_OP); }
+"||"            {  return(OR_OP); }
+"^^"            {  return(XOR_OP); }
+"<="            {  return(LE_OP); }
+">="            {  return(GE_OP); }
+"=="            {  return(EQ_OP); }
+"!="            {  return(NE_OP); }
+"<<"            {  return(LEFT_OP); }
+">>"            {  return(RIGHT_OP); }
+";"             { context->lexAfterType = false; return(SEMICOLON); }
+("{"|"<%")      { context->lexAfterType = false; return(LEFT_BRACE); }
+("}"|"%>")      { return(RIGHT_BRACE); }
+","         { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
+":"         { return(COLON); }
+"="         { context->lexAfterType = false; return(EQUAL); }
+"("         { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
+")"         { context->inTypeParen = false; return(RIGHT_PAREN); }
+("["|"<:")      { return(LEFT_BRACKET); }
+("]"|":>")      { return(RIGHT_BRACKET); }
 "."         { BEGIN(FIELDS);  return(DOT); }
-"!"         {  pyylval->lex.line = yylineno; return(BANG); }
-"-"         {  pyylval->lex.line = yylineno; return(DASH); }
-"~"         {  pyylval->lex.line = yylineno; return(TILDE); }
-"+"         {  pyylval->lex.line = yylineno; return(PLUS); }
-"*"         {  pyylval->lex.line = yylineno; return(STAR); }
-"/"         {  pyylval->lex.line = yylineno; return(SLASH); }
-"%"         {  pyylval->lex.line = yylineno; return(PERCENT); }
-"<"         {  pyylval->lex.line = yylineno; return(LEFT_ANGLE); }
-">"         {  pyylval->lex.line = yylineno; return(RIGHT_ANGLE); }
-"|"         {  pyylval->lex.line = yylineno; return(VERTICAL_BAR); }
-"^"         {  pyylval->lex.line = yylineno; return(CARET); }
-"&"         {  pyylval->lex.line = yylineno; return(AMPERSAND); }
-"?"         {  pyylval->lex.line = yylineno; return(QUESTION); }
+"!"         { return(BANG); }
+"-"         { return(DASH); }
+"~"         { return(TILDE); }
+"+"         { return(PLUS); }
+"*"         { return(STAR); }
+"/"         { return(SLASH); }
+"%"         { return(PERCENT); }
+"<"         { return(LEFT_ANGLE); }
+">"         { return(RIGHT_ANGLE); }
+"|"         { return(VERTICAL_BAR); }
+"^"         { return(CARET); }
+"&"         { return(AMPERSAND); }
+"?"         { return(QUESTION); }
 
 <FIELDS>{L}({L}|{D})* { 
-BEGIN(INITIAL);      
-    pyylval->lex.line = yylineno;     
-    pyylval->lex.string = NewPoolTString(yytext); 
-    return FIELD_SELECTION; }
+    BEGIN(INITIAL);
+    yylval->lex.string = NewPoolTString(yytext); 
+    return FIELD_SELECTION;
+}
 <FIELDS>[ \t\v\f\r] {}
 
 [ \t\v\n\f\r]   {  }
-<*><<EOF>> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();}
-<*>.    { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n";
-          return 0; }
+<*><<EOF>>      { context->AfterEOF = true; yyterminate(); }
+<*>.            { context->warning(yylineno, "Unknown char", yytext, ""); return 0; }
 
 %%
 
-
-//Including Pre-processor.
 extern "C" {
-  #include "compiler/preprocessor/preprocess.h"
-} 
+// Preprocessor interface.
+#include "compiler/preprocessor/preprocess.h"
 
-//
-// The YY_INPUT macro just calls this.  Maybe this could be just put into
-// the macro directly.
-//
+#define SETUP_CONTEXT(pp) \
+    TParseContext* context = (TParseContext*) pp->pC; \
+    struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
 
-int yy_input(char* buf, int max_size)
-{
-    int len;
-
-    if ((len = yylex_CPP(buf, max_size)) == 0)
-        return 0;
-    if (len >= max_size) 
-        YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-
-    buf[len] = ' ';
-	return len+1;
-}
-
-
-//
-// Parse an array of strings using yyparse.  We set up globals used by
-// yywrap.
-//
-// Returns 0 for success, as per yyparse().
-//
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal)
-{
-    int argv0len;
-    
-    ScanFromString(argv[0]); 
-    
-    //Storing the Current Compiler Parse context into the cpp structure.
-	cpp->pC = (void*)&parseContextLocal;
-	
-	if (!argv || argc == 0)
-        return 1;
-    
-    for (int i = 0; i < argc; ++i) {
-        if (!argv[i]) {
-            parseContextLocal.error(0, "Null shader source string", "", "");
-            parseContextLocal.recover();
-            return 1;
-        }
-    }
-    
-    if (!strLen) {
-        argv0len = (int) strlen(argv[0]);
-        strLen   = &argv0len;
-    }
-    yyrestart(0);
-    (&parseContextLocal)->AfterEOF = false;
-    cpp->PaWhichStr = 0;
-    cpp->PaArgv     = argv;
-    cpp->PaArgc     = argc;
-    cpp->PaStrLen   = strLen;
-    cpp->pastFirstStatement = 0;
-    yylineno   = 1;
-   
-    if (*cpp->PaStrLen >= 0) {    
-        int ret = yyparse((void*)(&parseContextLocal));
-        if (ret || cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
-             return 1;
-        else
-             return 0;
-    }
-    else
-        return 0;
-}
-
-void yyerror(const char *s) 
-{
-    if (((TParseContext *)cpp->pC)->AfterEOF) {
-        if (cpp->tokensBeforeEOF == 1) {
-            GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, "");
-            GlobalParseContext->recover();
-        }
-    } else {
-        GlobalParseContext->error(yylineno, "syntax error", yytext, s, "");
-        GlobalParseContext->recover();
-    }            
-}
-
-void PaReservedWord()
-{
-    GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", "");
-    GlobalParseContext->recover();
-}
-
-int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol)
-{
-    symbol = parseContextLocal.symbolTable.find(id);
-    if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) {
-        TVariable* variable = static_cast<TVariable*>(symbol);
-        if (variable->isUserType()) {
-            parseContextLocal.lexAfterType = true;
-            return TYPE_NAME;
-        }
-    }
-    
-    return IDENTIFIER;
-}
-
-int PaParseComment(int &lineno, TParseContext& parseContextLocal)
-{
-    int transitionFlag = 0;
-    int nextChar;
-    
-    while (transitionFlag != 2) {
-        nextChar = yyinput();
-        if (nextChar == '\n')
-             lineno++;
-        switch (nextChar) {
-        case '*' :
-            transitionFlag = 1;
-            break;
-        case '/' :  /* if star is the previous character, then it is the end of comment */
-            if (transitionFlag == 1) {
-                return 1 ;
-            }
-            break;
-        case EOF :
-            /* Raise error message here */
-            parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", "");
-            GlobalParseContext->recover();
-            return YY_NULL; 
-        default :  /* Any other character will be a part of the comment */
-            transitionFlag = 0;
-        }
-    }
-    return 1;
-}
-
-extern "C" {
-
+// Preprocessor callbacks.
 void CPPDebugLogMsg(const char *msg)
 {
-    ((TParseContext *)cpp->pC)->infoSink.debug.message(EPrefixNone, msg);
+    SETUP_CONTEXT(cpp);
+    context->infoSink.debug.message(EPrefixNone, msg);
 }
 
 void CPPWarningToInfoLog(const char *msg)
 {
-    ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg, yylineno); 
+    SETUP_CONTEXT(cpp);
+    context->warning(yylineno, msg, "", "");
 }
 
 void CPPShInfoLogMsg(const char *msg)
 {
-    ((TParseContext *)cpp->pC)->error(yylineno,"", "",msg,"");
-    GlobalParseContext->recover();
+    SETUP_CONTEXT(cpp);
+    context->error(yylineno, msg, "", "");
+    context->recover();
 }
 
 void CPPErrorToInfoLog(char *msg)
 {
-    ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,"");
-    GlobalParseContext->recover();
+    SETUP_CONTEXT(cpp);
+    context->error(yylineno, msg, "", "");
+    context->recover();
 }
 
 void SetLineNumber(int line)
 {
-    yylineno &= ~SourceLocLineMask;
-    yylineno |= line;
+    SETUP_CONTEXT(cpp);
+    int string = 0;
+    DecodeSourceLoc(yylineno, &string, NULL);
+    yylineno = EncodeSourceLoc(string, line);
 }
 
 void SetStringNumber(int string)
 {
-    yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask);
+    SETUP_CONTEXT(cpp);
+    int line = 0;
+    DecodeSourceLoc(yylineno, NULL, &line);
+    yylineno = EncodeSourceLoc(string, line);
 }
 
-int GetStringNumber(void)
+int GetStringNumber()
 {
-    return yylineno >> 16;
+    SETUP_CONTEXT(cpp);
+    int string = 0;
+    DecodeSourceLoc(yylineno, &string, NULL);
+    return string;
 }
 
-int GetLineNumber(void)
+int GetLineNumber()
 {
-    return yylineno & SourceLocLineMask;
+    SETUP_CONTEXT(cpp);
+    int line = 0;
+    DecodeSourceLoc(yylineno, NULL, &line);
+    return line;
 }
 
-void IncLineNumber(void)
+void IncLineNumber()
 {
-    if ((yylineno & SourceLocLineMask) <= SourceLocLineMask)
-        ++yylineno;
+    SETUP_CONTEXT(cpp);
+    int string = 0, line = 0;
+    DecodeSourceLoc(yylineno, &string, &line);
+    yylineno = EncodeSourceLoc(string, ++line);
 }
 
-void DecLineNumber(void)
+void DecLineNumber()
 {
-    if ((yylineno & SourceLocLineMask) > 0)
-        --yylineno;
+    SETUP_CONTEXT(cpp);
+    int string = 0, line = 0;
+    DecodeSourceLoc(yylineno, &string, &line);
+    yylineno = EncodeSourceLoc(string, --line);
 }
 
 void HandlePragma(const char **tokens, int numTokens)
-{    
+{
+    SETUP_CONTEXT(cpp);
     if (!strcmp(tokens[0], "optimize")) {
         if (numTokens != 4) {
             CPPShInfoLogMsg("optimize pragma syntax is incorrect");
@@ -452,9 +344,9 @@
         }
             
         if (!strcmp(tokens[2], "on"))
-            ((TParseContext *)cpp->pC)->contextPragma.optimize = true;
+            context->contextPragma.optimize = true;
         else if (!strcmp(tokens[2], "off"))
-            ((TParseContext *)cpp->pC)->contextPragma.optimize = false;
+            context->contextPragma.optimize = false;
         else {
             CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
             return;
@@ -476,9 +368,9 @@
         }
             
         if (!strcmp(tokens[2], "on"))
-            ((TParseContext *)cpp->pC)->contextPragma.debug = true;
+            context->contextPragma.debug = true;
         else if (!strcmp(tokens[2], "off"))
-            ((TParseContext *)cpp->pC)->contextPragma.debug = false;
+            context->contextPragma.debug = false;
         else {
             CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
             return;
@@ -489,7 +381,6 @@
             return;
         }
     } else {
-
 #ifdef PRAGMA_TABLE
         //
         // implementation specific pragma
@@ -524,21 +415,24 @@
 
 void StoreStr(char *string)
 {
+    SETUP_CONTEXT(cpp);
     TString strSrc;
     strSrc = TString(string);
 
-    ((TParseContext *)cpp->pC)->HashErrMsg = ((TParseContext *)cpp->pC)->HashErrMsg + " " + strSrc;
+    context->HashErrMsg = context->HashErrMsg + " " + strSrc;
 }
 
 const char* GetStrfromTStr(void)
 {
-    cpp->ErrMsg = (((TParseContext *)cpp->pC)->HashErrMsg).c_str();
+    SETUP_CONTEXT(cpp);
+    cpp->ErrMsg = context->HashErrMsg.c_str();
     return cpp->ErrMsg;
 }
 
 void ResetTString(void)
 {
-    ((TParseContext *)cpp->pC)->HashErrMsg = "";
+    SETUP_CONTEXT(cpp);
+    context->HashErrMsg = "";
 }
 
 TBehavior GetBehavior(const char* behavior)
@@ -557,8 +451,9 @@
     }        
 }
 
-void  updateExtensionBehavior(const char* extName, const char* behavior)
+void updateExtensionBehavior(const char* extName, const char* behavior)
 {
+    SETUP_CONTEXT(cpp);
     TBehavior behaviorVal = GetBehavior(behavior);
     TMap<TString, TBehavior>:: iterator iter;
     TString msg;
@@ -569,12 +464,12 @@
             CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");  
             return;
         } else {
-            for (iter =  ((TParseContext *)cpp->pC)->extensionBehavior.begin(); iter != ((TParseContext *)cpp->pC)->extensionBehavior.end(); ++iter)
+            for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter)
                 iter->second = behaviorVal;
         }        
     } else {
-        iter = ((TParseContext *)cpp->pC)->extensionBehavior.find(TString(extName));
-        if (iter == ((TParseContext *)cpp->pC)->extensionBehavior.end()) {
+        iter = context->extensionBehavior.find(TString(extName));
+        if (iter == context->extensionBehavior.end()) {
             switch (behaviorVal) {
             case EBhRequire:
                 CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());  
@@ -583,7 +478,7 @@
             case EBhWarn:
             case EBhDisable:
                 msg = TString("extension '") + extName + "' is not supported";
-                ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); 
+                context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); 
                 break;
             }
             return;
@@ -591,10 +486,85 @@
             iter->second = behaviorVal;
     }
 }
-        
 }  // extern "C"
 
-void setInitialState()
-{
-    yy_start = 1;
+int string_input(char* buf, int max_size, yyscan_t yyscanner) {
+    int len;
+
+    if ((len = yylex_CPP(buf, max_size)) == 0)
+        return 0;
+    if (len >= max_size) 
+        YY_FATAL_ERROR("input buffer overflow, can't enlarge buffer because scanner uses REJECT");
+
+    buf[len] = ' ';
+    return len+1;
 }
+
+int check_type(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+    
+    int token = IDENTIFIER;
+    TSymbol* symbol = yyextra->symbolTable.find(yytext);
+    if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
+        TVariable* variable = static_cast<TVariable*>(symbol);
+        if (variable->isUserType()) {
+            yyextra->lexAfterType = true;
+            token = TYPE_NAME;
+        }
+    }
+    yylval->lex.symbol = symbol;
+    return token;
+}
+
+int reserved_word(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+    yyextra->error(yylineno, "Illegal use of reserved word", yytext, "");
+    yyextra->recover();
+    return 0;
+}
+
+void yyerror(TParseContext* context, const char* reason) {
+    struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
+
+    if (context->AfterEOF) {
+        context->error(yylineno, reason, "unexpected EOF", "");
+    } else {
+        context->error(yylineno, reason, yytext, "");
+    }
+    context->recover();
+}
+
+int glslang_initialize(TParseContext* context) {
+    yyscan_t scanner = NULL;
+    if (yylex_init_extra(context, &scanner))
+        return 1;
+
+    context->scanner = scanner;
+    return 0;
+}
+
+int glslang_finalize(TParseContext* context) {
+    yyscan_t scanner = context->scanner;
+    if (scanner == NULL) return 0;
+    
+    context->scanner = NULL;
+    return yylex_destroy(scanner);
+}
+
+void glslang_scan(int count, const char* const string[], const int length[],
+                  TParseContext* context) {
+    yyrestart(NULL, context->scanner);
+    yyset_lineno(EncodeSourceLoc(0, 1), context->scanner);
+    context->AfterEOF = false;
+    
+    // Init preprocessor.
+    cpp->pC = context;
+    cpp->PaWhichStr = 0;
+    cpp->PaArgv     = string;
+    cpp->PaArgc     = count;
+    cpp->PaStrLen   = length;
+    cpp->pastFirstStatement = 0;
+    ScanFromString(string[0]);
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.y b/Source/ThirdParty/ANGLE/src/compiler/glslang.y
index d0d29df..5eae4b5 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/glslang.y
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.y
@@ -1,89 +1,38 @@
+/*
 //
 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
-/**
- * This is bison grammar and production code for parsing the OpenGL 2.0 shading
- * languages.
- */
-%{
+This file contains the Yacc grammar for GLSL ES.
+Based on ANSI C Yacc grammar:
+http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
 
-/* Based on:
-ANSI C Yacc grammar
-
-In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a
-matching Lex specification) for the April 30, 1985 draft version of the
-ANSI C standard.  Tom Stockfisch reposted it to net.sources in 1987; that
-original, as mentioned in the answer to question 17.25 of the comp.lang.c
-FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z.
-
-I intend to keep this version as close to the current C Standard grammar as
-possible; please let me know if you discover discrepancies.
-
-Jutta Degener, 1995
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_parser.sh,
+WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
 */
 
+%{
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
+
 #include "compiler/SymbolTable.h"
 #include "compiler/ParseHelper.h"
 #include "GLSLANG/ShaderLang.h"
 
-#define YYPARSE_PARAM parseContextLocal
-/*
-TODO(alokp): YYPARSE_PARAM_DECL is only here to support old bison.exe in
-compiler/tools. Remove it when we can exclusively use the newer version.
-*/
-#define YYPARSE_PARAM_DECL void*
-#define parseContext ((TParseContext*)(parseContextLocal))
-#define YYLEX_PARAM parseContextLocal
-#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
-extern void yyerror(const char*);
-
-#define FRAG_VERT_ONLY(S, L) {                                                  \
-    if (parseContext->language != EShLangFragment &&                             \
-        parseContext->language != EShLangVertex) {                               \
-        parseContext->error(L, " supported in vertex/fragment shaders only ", S, "", "");   \
-        parseContext->recover();                                                            \
-    }                                                                           \
-}
-
-#define VERTEX_ONLY(S, L) {                                                     \
-    if (parseContext->language != EShLangVertex) {                               \
-        parseContext->error(L, " supported in vertex shaders only ", S, "", "");            \
-        parseContext->recover();                                                            \
-    }                                                                           \
-}
-
-#define FRAG_ONLY(S, L) {                                                       \
-    if (parseContext->language != EShLangFragment) {                             \
-        parseContext->error(L, " supported in fragment shaders only ", S, "", "");          \
-        parseContext->recover();                                                            \
-    }                                                                           \
-}
-
-#define PACK_ONLY(S, L) {                                                       \
-    if (parseContext->language != EShLangPack) {                                 \
-        parseContext->error(L, " supported in pack shaders only ", S, "", "");              \
-        parseContext->recover();                                                            \
-    }                                                                           \
-}
-
-#define UNPACK_ONLY(S, L) {                                                     \
-    if (parseContext->language != EShLangUnpack) {                               \
-        parseContext->error(L, " supported in unpack shaders only ", S, "", "");            \
-        parseContext->recover();                                                            \
-    }                                                                           \
-}
-
-#define PACK_UNPACK_ONLY(S, L) {                                                \
-    if (parseContext->language != EShLangUnpack &&                               \
-        parseContext->language != EShLangPack) {                                 \
-        parseContext->error(L, " supported in pack/unpack shaders only ", S, "", "");       \
-        parseContext->recover();                                                            \
-    }                                                                           \
-}
+#define YYLEX_PARAM context->scanner
 %}
+
+%expect 1 /* One shift reduce conflict because of if | else */
+%pure-parser
+%parse-param {TParseContext* context}
+
 %union {
     struct {
         TSourceLoc line;
@@ -117,11 +66,32 @@
 }
 
 %{
-    extern int yylex(YYSTYPE*, void*);
+extern int yylex(YYSTYPE* yylval_param, void* yyscanner);
+extern void yyerror(TParseContext* context, const char* reason);
+
+#define FRAG_VERT_ONLY(S, L) {  \
+    if (context->shaderType != SH_FRAGMENT_SHADER &&  \
+        context->shaderType != SH_VERTEX_SHADER) {  \
+        context->error(L, " supported in vertex/fragment shaders only ", S, "", "");  \
+        context->recover();  \
+    }  \
+}
+
+#define VERTEX_ONLY(S, L) {  \
+    if (context->shaderType != SH_VERTEX_SHADER) {  \
+        context->error(L, " supported in vertex shaders only ", S, "", "");  \
+        context->recover();  \
+    }  \
+}
+
+#define FRAG_ONLY(S, L) {  \
+    if (context->shaderType != SH_FRAGMENT_SHADER) {  \
+        context->error(L, " supported in fragment shaders only ", S, "", "");  \
+        context->recover();  \
+    }  \
+}
 %}
 
-%pure_parser /* Just in case is called from multiple threads */
-%expect 1 /* One shift reduce conflict because of if | else */
 %token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
 %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
 %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
@@ -185,17 +155,17 @@
         const TSymbol* symbol = $1.symbol;
         const TVariable* variable;
         if (symbol == 0) {
-            parseContext->error($1.line, "undeclared identifier", $1.string->c_str(), "");
-            parseContext->recover();
+            context->error($1.line, "undeclared identifier", $1.string->c_str(), "");
+            context->recover();
             TType type(EbtFloat, EbpUndefined);
             TVariable* fakeVariable = new TVariable($1.string, type);
-            parseContext->symbolTable.insert(*fakeVariable);
+            context->symbolTable.insert(*fakeVariable);
             variable = fakeVariable;
         } else {
             // This identifier can only be a variable type symbol
             if (! symbol->isVariable()) {
-                parseContext->error($1.line, "variable expected", $1.string->c_str(), "");
-                parseContext->recover();
+                context->error($1.line, "variable expected", $1.string->c_str(), "");
+                context->recover();
             }
             variable = static_cast<const TVariable*>(symbol);
         }
@@ -206,9 +176,9 @@
         if (variable->getType().getQualifier() == EvqConst ) {
             ConstantUnion* constArray = variable->getConstPointer();
             TType t(variable->getType());
-            $$ = parseContext->intermediate.addConstantUnion(constArray, t, $1.line);
+            $$ = context->intermediate.addConstantUnion(constArray, t, $1.line);
         } else
-            $$ = parseContext->intermediate.addSymbol(variable->getUniqueId(),
+            $$ = context->intermediate.addSymbol(variable->getUniqueId(),
                                                      variable->getName(),
                                                      variable->getType(), $1.line);
     }
@@ -224,22 +194,22 @@
         // check for overflow for constants
         //
         if (abs($1.i) >= (1 << 16)) {
-            parseContext->error($1.line, " integer constant overflow", "", "");
-            parseContext->recover();
+            context->error($1.line, " integer constant overflow", "", "");
+            context->recover();
         }
         ConstantUnion *unionArray = new ConstantUnion[1];
         unionArray->setIConst($1.i);
-        $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line);
+        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line);
     }
     | FLOATCONSTANT {
         ConstantUnion *unionArray = new ConstantUnion[1];
         unionArray->setFConst($1.f);
-        $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
+        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
     }
     | BOOLCONSTANT {
         ConstantUnion *unionArray = new ConstantUnion[1];
         unionArray->setBConst($1.b);
-        $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $1.line);
+        $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $1.line);
     }
     | LEFT_PAREN expression RIGHT_PAREN {
         $$ = $2;
@@ -253,57 +223,57 @@
     | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
         if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
             if ($1->getAsSymbolNode())
-                parseContext->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), "");
+                context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), "");
             else
-                parseContext->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
-            parseContext->recover();
+                context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
+            context->recover();
         }
         if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
             if ($1->isArray()) { // constant folding for arrays
-                $$ = parseContext->addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
+                $$ = context->addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
             } else if ($1->isVector()) {  // constant folding for vectors
                 TVectorFields fields;
                 fields.num = 1;
                 fields.offsets[0] = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); // need to do it this way because v.xy sends fields integer array
-                $$ = parseContext->addConstVectorNode(fields, $1, $2.line);
+                $$ = context->addConstVectorNode(fields, $1, $2.line);
             } else if ($1->isMatrix()) { // constant folding for matrices
-                $$ = parseContext->addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
+                $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
             }
         } else {
             if ($3->getQualifier() == EvqConst) {
                 if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) {
-                    parseContext->error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
-                    parseContext->recover();
+                    context->error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+                    context->recover();
                 } else {
                     if ($1->isArray()) {
                         if ($1->getType().getArraySize() == 0) {
                             if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) {
-                                if (parseContext->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line))
-                                    parseContext->recover();
+                                if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line))
+                                    context->recover();
                             } else {
-                                if (parseContext->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
-                                    parseContext->recover();
+                                if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
+                                    context->recover();
                             }
                         } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) {
-                            parseContext->error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
-                            parseContext->recover();
+                            context->error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+                            context->recover();
                         }
                     }
-                    $$ = parseContext->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
+                    $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
                 }
             } else {
                 if ($1->isArray() && $1->getType().getArraySize() == 0) {
-                    parseContext->error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
-                    parseContext->recover();
+                    context->error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
+                    context->recover();
                 }
 
-                $$ = parseContext->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
+                $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
             }
         }
         if ($$ == 0) {
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setFConst(0.0f);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), $2.line);
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), $2.line);
         } else if ($1->isArray()) {
             if ($1->getType().getStruct())
                 $$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
@@ -328,22 +298,22 @@
     }
     | postfix_expression DOT FIELD_SELECTION {
         if ($1->isArray()) {
-            parseContext->error($3.line, "cannot apply dot operator to an array", ".", "");
-            parseContext->recover();
+            context->error($3.line, "cannot apply dot operator to an array", ".", "");
+            context->recover();
         }
 
         if ($1->isVector()) {
             TVectorFields fields;
-            if (! parseContext->parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
+            if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
                 fields.num = 1;
                 fields.offsets[0] = 0;
-                parseContext->recover();
+                context->recover();
             }
 
             if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
-                $$ = parseContext->addConstVectorNode(fields, $1, $3.line);
+                $$ = context->addConstVectorNode(fields, $1, $3.line);
                 if ($$ == 0) {
-                    parseContext->recover();
+                    context->recover();
                     $$ = $1;
                 }
                 else
@@ -352,47 +322,47 @@
                 if (fields.num == 1) {
                     ConstantUnion *unionArray = new ConstantUnion[1];
                     unionArray->setIConst(fields.offsets[0]);
-                    TIntermTyped* index = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
-                    $$ = parseContext->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+                    TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
+                    $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
                     $$->setType(TType($1->getBasicType(), $1->getPrecision()));
                 } else {
                     TString vectorString = *$3.string;
-                    TIntermTyped* index = parseContext->intermediate.addSwizzle(fields, $3.line);
-                    $$ = parseContext->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
+                    TIntermTyped* index = context->intermediate.addSwizzle(fields, $3.line);
+                    $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
                     $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size()));
                 }
             }
         } else if ($1->isMatrix()) {
             TMatrixFields fields;
-            if (! parseContext->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
+            if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
                 fields.wholeRow = false;
                 fields.wholeCol = false;
                 fields.row = 0;
                 fields.col = 0;
-                parseContext->recover();
+                context->recover();
             }
 
             if (fields.wholeRow || fields.wholeCol) {
-                parseContext->error($2.line, " non-scalar fields not implemented yet", ".", "");
-                parseContext->recover();
+                context->error($2.line, " non-scalar fields not implemented yet", ".", "");
+                context->recover();
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setIConst(0);
-                TIntermTyped* index = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
-                $$ = parseContext->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
+                $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
                 $$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize()));
             } else {
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);
-                TIntermTyped* index = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
-                $$ = parseContext->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
+                $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
                 $$->setType(TType($1->getBasicType(), $1->getPrecision()));
             }
         } else if ($1->getBasicType() == EbtStruct) {
             bool fieldFound = false;
             const TTypeList* fields = $1->getType().getStruct();
             if (fields == 0) {
-                parseContext->error($2.line, "structure has no fields", "Internal Error", "");
-                parseContext->recover();
+                context->error($2.line, "structure has no fields", "Internal Error", "");
+                context->recover();
                 $$ = $1;
             } else {
                 unsigned int i;
@@ -404,9 +374,9 @@
                 }
                 if (fieldFound) {
                     if ($1->getType().getQualifier() == EvqConst) {
-                        $$ = parseContext->addConstStruct(*$3.string, $1, $2.line);
+                        $$ = context->addConstStruct(*$3.string, $1, $2.line);
                         if ($$ == 0) {
-                            parseContext->recover();
+                            context->recover();
                             $$ = $1;
                         }
                         else {
@@ -418,40 +388,40 @@
                     } else {
                         ConstantUnion *unionArray = new ConstantUnion[1];
                         unionArray->setIConst(i);
-                        TIntermTyped* index = parseContext->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, $3.line);
-                        $$ = parseContext->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
+                        TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, $3.line);
+                        $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
                         $$->setType(*(*fields)[i].type);
                     }
                 } else {
-                    parseContext->error($2.line, " no such field in structure", $3.string->c_str(), "");
-                    parseContext->recover();
+                    context->error($2.line, " no such field in structure", $3.string->c_str(), "");
+                    context->recover();
                     $$ = $1;
                 }
             }
         } else {
-            parseContext->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");
-            parseContext->recover();
+            context->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");
+            context->recover();
             $$ = $1;
         }
         // don't delete $3.string, it's from the pool
     }
     | postfix_expression INC_OP {
-        if (parseContext->lValueErrorCheck($2.line, "++", $1))
-            parseContext->recover();
-        $$ = parseContext->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, parseContext->symbolTable);
+        if (context->lValueErrorCheck($2.line, "++", $1))
+            context->recover();
+        $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->unaryOpError($2.line, "++", $1->getCompleteString());
-            parseContext->recover();
+            context->unaryOpError($2.line, "++", $1->getCompleteString());
+            context->recover();
             $$ = $1;
         }
     }
     | postfix_expression DEC_OP {
-        if (parseContext->lValueErrorCheck($2.line, "--", $1))
-            parseContext->recover();
-        $$ = parseContext->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, parseContext->symbolTable);
+        if (context->lValueErrorCheck($2.line, "--", $1))
+            context->recover();
+        $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->unaryOpError($2.line, "--", $1->getCompleteString());
-            parseContext->recover();
+            context->unaryOpError($2.line, "--", $1->getCompleteString());
+            context->recover();
             $$ = $1;
         }
     }
@@ -459,8 +429,8 @@
 
 integer_expression
     : expression {
-        if (parseContext->integerErrorCheck($1, "[]"))
-            parseContext->recover();
+        if (context->integerErrorCheck($1, "[]"))
+            context->recover();
         $$ = $1;
     }
     ;
@@ -478,18 +448,18 @@
             // Their parameters will be verified algorithmically.
             //
             TType type(EbtVoid, EbpUndefined);  // use this to get the type back
-            if (parseContext->constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) {
+            if (context->constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) {
                 $$ = 0;
             } else {
                 //
                 // It's a constructor, of type 'type'.
                 //
-                $$ = parseContext->addConstructor($1.intermNode, &type, op, fnCall, $1.line);
+                $$ = context->addConstructor($1.intermNode, &type, op, fnCall, $1.line);
             }
 
             if ($$ == 0) {
-                parseContext->recover();
-                $$ = parseContext->intermediate.setAggregateOperator(0, op, $1.line);
+                context->recover();
+                $$ = context->intermediate.setAggregateOperator(0, op, $1.line);
             }
             $$->setType(type);
         } else {
@@ -498,12 +468,15 @@
             //
             const TFunction* fnCandidate;
             bool builtIn;
-            fnCandidate = parseContext->findFunction($1.line, fnCall, &builtIn);
+            fnCandidate = context->findFunction($1.line, fnCall, &builtIn);
             if (fnCandidate) {
                 //
-                // A declared function.  But, it might still map to a built-in
-                // operation.
+                // A declared function.
                 //
+                if (builtIn && !fnCandidate->getExtension().empty() &&
+                    context->extensionErrorCheck($1.line, fnCandidate->getExtension())) {
+                    context->recover();
+                }
                 op = fnCandidate->getBuiltInOp();
                 if (builtIn && op != EOpNull) {
                     //
@@ -513,20 +486,20 @@
                         //
                         // Treat it like a built-in unary operator.
                         //
-                        $$ = parseContext->intermediate.addUnaryMath(op, $1.intermNode, 0, parseContext->symbolTable);
+                        $$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable);
                         if ($$ == 0)  {
-                            parseContext->error($1.intermNode->getLine(), " wrong operand type", "Internal Error",
+                            context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error",
                                 "built in unary operator function.  Type: %s",
                                 static_cast<TIntermTyped*>($1.intermNode)->getCompleteString().c_str());
                             YYERROR;
                         }
                     } else {
-                        $$ = parseContext->intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
+                        $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
                     }
                 } else {
                     // This is a real function call
 
-                    $$ = parseContext->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
+                    $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
                     $$->setType(fnCandidate->getReturnType());
 
                     // this is how we know whether the given function is a builtIn function or a user defined function
@@ -537,16 +510,14 @@
                     $$->getAsAggregate()->setName(fnCandidate->getMangledName());
 
                     TQualifier qual;
-                    TQualifierList& qualifierList = $$->getAsAggregate()->getQualifier();
                     for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
-                        qual = (*fnCandidate)[i].type->getQualifier();
+                        qual = fnCandidate->getParam(i).type->getQualifier();
                         if (qual == EvqOut || qual == EvqInOut) {
-                            if (parseContext->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
-                                parseContext->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
-                                parseContext->recover();
+                            if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
+                                context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
+                                context->recover();
                             }
                         }
-                        qualifierList.push_back(qual);
                     }
                 }
                 $$->setType(fnCandidate->getReturnType());
@@ -555,8 +526,8 @@
                 // Put on a dummy node for error recovery
                 ConstantUnion *unionArray = new ConstantUnion[1];
                 unionArray->setFConst(0.0f);
-                $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
-                parseContext->recover();
+                $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
+                context->recover();
             }
         }
         delete fnCall;
@@ -568,8 +539,8 @@
         $$ = $1;
     }
     | postfix_expression DOT function_call_generic {
-        parseContext->error($3.line, "methods are not supported", "", "");
-        parseContext->recover();
+        context->error($3.line, "methods are not supported", "", "");
+        context->recover();
         $$ = $3;
     }
     ;
@@ -607,7 +578,7 @@
         TParameter param = { 0, new TType($3->getType()) };
         $1.function->addParameter(param);
         $$.function = $1.function;
-        $$.intermNode = parseContext->intermediate.growAggregate($1.intermNode, $3, $2.line);
+        $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, $2.line);
     }
     ;
 
@@ -625,19 +596,16 @@
         // Constructor
         //
         if ($1.array) {
-            if (parseContext->extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
-                parseContext->recover();
-                $1.setArray(false);
-            }
+            // Constructors for arrays are not allowed.
+            context->error($1.line, "cannot construct this type", "array", "");
+            context->recover();
+            $1.setArray(false);
         }
 
+        TOperator op = EOpNull;
         if ($1.userDef) {
-            TString tempString = "";
-            TType type($1);
-            TFunction *function = new TFunction(&tempString, type, EOpConstructStruct);
-            $$ = function;
+            op = EOpConstructStruct;
         } else {
-            TOperator op = EOpNull;
             switch ($1.type) {
             case EbtFloat:
                 if ($1.matrix) {
@@ -671,29 +639,30 @@
                 case 4:       FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break;
                 }
                 break;
+            default: break;
             }
             if (op == EOpNull) {
-                parseContext->error($1.line, "cannot construct this type", getBasicString($1.type), "");
-                parseContext->recover();
+                context->error($1.line, "cannot construct this type", getBasicString($1.type), "");
+                context->recover();
                 $1.type = EbtFloat;
                 op = EOpConstructFloat;
             }
-            TString tempString = "";
-            TType type($1);
-            TFunction *function = new TFunction(&tempString, type, op);
-            $$ = function;
         }
+        TString tempString;
+        TType type($1);
+        TFunction *function = new TFunction(&tempString, type, op);
+        $$ = function;
     }
     | IDENTIFIER {
-        if (parseContext->reservedErrorCheck($1.line, *$1.string))
-            parseContext->recover();
+        if (context->reservedErrorCheck($1.line, *$1.string))
+            context->recover();
         TType type(EbtVoid, EbpUndefined);
         TFunction *function = new TFunction($1.string, type);
         $$ = function;
     }
     | FIELD_SELECTION {
-        if (parseContext->reservedErrorCheck($1.line, *$1.string))
-            parseContext->recover();
+        if (context->reservedErrorCheck($1.line, *$1.string))
+            context->recover();
         TType type(EbtVoid, EbpUndefined);
         TFunction *function = new TFunction($1.string, type);
         $$ = function;
@@ -705,28 +674,28 @@
         $$ = $1;
     }
     | INC_OP unary_expression {
-        if (parseContext->lValueErrorCheck($1.line, "++", $2))
-            parseContext->recover();
-        $$ = parseContext->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, parseContext->symbolTable);
+        if (context->lValueErrorCheck($1.line, "++", $2))
+            context->recover();
+        $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->unaryOpError($1.line, "++", $2->getCompleteString());
-            parseContext->recover();
+            context->unaryOpError($1.line, "++", $2->getCompleteString());
+            context->recover();
             $$ = $2;
         }
     }
     | DEC_OP unary_expression {
-        if (parseContext->lValueErrorCheck($1.line, "--", $2))
-            parseContext->recover();
-        $$ = parseContext->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, parseContext->symbolTable);
+        if (context->lValueErrorCheck($1.line, "--", $2))
+            context->recover();
+        $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->unaryOpError($1.line, "--", $2->getCompleteString());
-            parseContext->recover();
+            context->unaryOpError($1.line, "--", $2->getCompleteString());
+            context->recover();
             $$ = $2;
         }
     }
     | unary_operator unary_expression {
         if ($1.op != EOpNull) {
-            $$ = parseContext->intermediate.addUnaryMath($1.op, $2, $1.line, parseContext->symbolTable);
+            $$ = context->intermediate.addUnaryMath($1.op, $2, $1.line, context->symbolTable);
             if ($$ == 0) {
                 const char* errorOp = "";
                 switch($1.op) {
@@ -734,8 +703,8 @@
                 case EOpLogicalNot: errorOp = "!"; break;
                 default: break;
                 }
-                parseContext->unaryOpError($1.line, errorOp, $2->getCompleteString());
-                parseContext->recover();
+                context->unaryOpError($1.line, errorOp, $2->getCompleteString());
+                context->recover();
                 $$ = $2;
             }
         } else
@@ -755,19 +724,19 @@
     : unary_expression { $$ = $1; }
     | multiplicative_expression STAR unary_expression {
         FRAG_VERT_ONLY("*", $2.line);
-        $$ = parseContext->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             $$ = $1;
         }
     }
     | multiplicative_expression SLASH unary_expression {
         FRAG_VERT_ONLY("/", $2.line);
-        $$ = parseContext->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             $$ = $1;
         }
     }
@@ -776,18 +745,18 @@
 additive_expression
     : multiplicative_expression { $$ = $1; }
     | additive_expression PLUS multiplicative_expression {
-        $$ = parseContext->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             $$ = $1;
         }
     }
     | additive_expression DASH multiplicative_expression {
-        $$ = parseContext->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             $$ = $1;
         }
     }
@@ -800,43 +769,43 @@
 relational_expression
     : shift_expression { $$ = $1; }
     | relational_expression LEFT_ANGLE shift_expression {
-        $$ = parseContext->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
         }
     }
     | relational_expression RIGHT_ANGLE shift_expression  {
-        $$ = parseContext->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
         }
     }
     | relational_expression LE_OP shift_expression  {
-        $$ = parseContext->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
         }
     }
     | relational_expression GE_OP shift_expression  {
-        $$ = parseContext->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
         }
     }
     ;
@@ -844,26 +813,24 @@
 equality_expression
     : relational_expression { $$ = $1; }
     | equality_expression EQ_OP relational_expression  {
-        $$ = parseContext->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
-        } else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
-            parseContext->recover();
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+        }
     }
     | equality_expression NE_OP relational_expression {
-        $$ = parseContext->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
-        } else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
-            parseContext->recover();
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+        }
     }
     ;
 
@@ -882,13 +849,13 @@
 logical_and_expression
     : inclusive_or_expression { $$ = $1; }
     | logical_and_expression AND_OP inclusive_or_expression {
-        $$ = parseContext->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
         }
     }
     ;
@@ -896,13 +863,13 @@
 logical_xor_expression
     : logical_and_expression { $$ = $1; }
     | logical_xor_expression XOR_OP logical_and_expression  {
-        $$ = parseContext->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
         }
     }
     ;
@@ -910,13 +877,13 @@
 logical_or_expression
     : logical_xor_expression { $$ = $1; }
     | logical_or_expression OR_OP logical_xor_expression  {
-        $$ = parseContext->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, parseContext->symbolTable);
+        $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, context->symbolTable);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             ConstantUnion *unionArray = new ConstantUnion[1];
             unionArray->setBConst(false);
-            $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+            $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
         }
     }
     ;
@@ -924,16 +891,16 @@
 conditional_expression
     : logical_or_expression { $$ = $1; }
     | logical_or_expression QUESTION expression COLON assignment_expression {
-       if (parseContext->boolErrorCheck($2.line, $1))
-            parseContext->recover();
+       if (context->boolErrorCheck($2.line, $1))
+            context->recover();
 
-        $$ = parseContext->intermediate.addSelection($1, $3, $5, $2.line);
+        $$ = context->intermediate.addSelection($1, $3, $5, $2.line);
         if ($3->getType() != $5->getType())
             $$ = 0;
 
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
+            context->recover();
             $$ = $5;
         }
     }
@@ -942,15 +909,14 @@
 assignment_expression
     : conditional_expression { $$ = $1; }
     | unary_expression assignment_operator assignment_expression {
-        if (parseContext->lValueErrorCheck($2.line, "assign", $1))
-            parseContext->recover();
-        $$ = parseContext->intermediate.addAssign($2.op, $1, $3, $2.line);
+        if (context->lValueErrorCheck($2.line, "assign", $1))
+            context->recover();
+        $$ = context->intermediate.addAssign($2.op, $1, $3, $2.line);
         if ($$ == 0) {
-            parseContext->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             $$ = $1;
-        } else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
-            parseContext->recover();
+        }
     }
     ;
 
@@ -967,10 +933,10 @@
         $$ = $1;
     }
     | expression COMMA assignment_expression {
-        $$ = parseContext->intermediate.addComma($1, $3, $2.line);
+        $$ = context->intermediate.addComma($1, $3, $2.line);
         if ($$ == 0) {
-            parseContext->binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
-            parseContext->recover();
+            context->binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
+            context->recover();
             $$ = $3;
         }
     }
@@ -978,8 +944,8 @@
 
 constant_expression
     : conditional_expression {
-        if (parseContext->constErrorCheck($1))
-            parseContext->recover();
+        if (context->constErrorCheck($1))
+            context->recover();
         $$ = $1;
     }
     ;
@@ -994,16 +960,16 @@
         
         for (int i = 0; i < function.getParamCount(); i++)
         {
-            TParameter &param = function[i];
+            const TParameter &param = function.getParam(i);
             if (param.name != 0)
             {
                 TVariable *variable = new TVariable(param.name, *param.type);
                 
-                prototype = parseContext->intermediate.growAggregate(prototype, parseContext->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), $1.line), $1.line);
+                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), $1.line), $1.line);
             }
             else
             {
-                prototype = parseContext->intermediate.growAggregate(prototype, parseContext->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
+                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
             }
         }
         
@@ -1016,7 +982,7 @@
         $$ = $1.intermAggregate;
     }
     | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
-        parseContext->symbolTable.setDefaultPrecision( $3.type, $2 );
+        context->symbolTable.setDefaultPrecision( $3.type, $2 );
         $$ = 0;
     }
     ;
@@ -1031,16 +997,16 @@
         //
         // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
         //
-        TFunction* prevDec = static_cast<TFunction*>(parseContext->symbolTable.find($1->getMangledName()));
+        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName()));
         if (prevDec) {
             if (prevDec->getReturnType() != $1->getReturnType()) {
-                parseContext->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString(), "");
-                parseContext->recover();
+                context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString(), "");
+                context->recover();
             }
             for (int i = 0; i < prevDec->getParamCount(); ++i) {
-                if ((*prevDec)[i].type->getQualifier() != (*$1)[i].type->getQualifier()) {
-                    parseContext->error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getQualifierString(), "");
-                    parseContext->recover();
+                if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) {
+                    context->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString(), "");
+                    context->recover();
                 }
             }
         }
@@ -1053,7 +1019,7 @@
         $$.function = $1;
         $$.line = $2.line;
 
-        parseContext->symbolTable.insert(*$$.function);
+        context->symbolTable.insert(*$$.function);
     }
     ;
 
@@ -1085,8 +1051,8 @@
             //
             // This parameter > first is void
             //
-            parseContext->error($2.line, "cannot be an argument type except for '(void)'", "void", "");
-            parseContext->recover();
+            context->error($2.line, "cannot be an argument type except for '(void)'", "void", "");
+            context->recover();
             delete $3.param.type;
         } else {
             // Add the parameter
@@ -1099,12 +1065,12 @@
 function_header
     : fully_specified_type IDENTIFIER LEFT_PAREN {
         if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
-            parseContext->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), "");
-            parseContext->recover();
+            context->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), "");
+            context->recover();
         }
         // make sure a sampler is not involved as well...
-        if (parseContext->structQualifierErrorCheck($2.line, $1))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($2.line, $1))
+            context->recover();
 
         // Add the function as a prototype after parsing it (we do not support recursion)
         TFunction *function;
@@ -1118,26 +1084,26 @@
     // Type + name
     : type_specifier IDENTIFIER {
         if ($1.type == EbtVoid) {
-            parseContext->error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
-            parseContext->recover();
+            context->error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
+            context->recover();
         }
-        if (parseContext->reservedErrorCheck($2.line, *$2.string))
-            parseContext->recover();
+        if (context->reservedErrorCheck($2.line, *$2.string))
+            context->recover();
         TParameter param = {$2.string, new TType($1)};
         $$.line = $2.line;
         $$.param = param;
     }
     | type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
         // Check that we can make an array out of this type
-        if (parseContext->arrayTypeErrorCheck($3.line, $1))
-            parseContext->recover();
+        if (context->arrayTypeErrorCheck($3.line, $1))
+            context->recover();
 
-        if (parseContext->reservedErrorCheck($2.line, *$2.string))
-            parseContext->recover();
+        if (context->reservedErrorCheck($2.line, *$2.string))
+            context->recover();
 
         int size;
-        if (parseContext->arraySizeErrorCheck($3.line, $4, size))
-            parseContext->recover();
+        if (context->arraySizeErrorCheck($3.line, $4, size))
+            context->recover();
         $1.setArray(true, size);
 
         TType* type = new TType($1);
@@ -1158,30 +1124,30 @@
     //
     : type_qualifier parameter_qualifier parameter_declarator {
         $$ = $3;
-        if (parseContext->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
-            parseContext->recover();
+        if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+            context->recover();
     }
     | parameter_qualifier parameter_declarator {
         $$ = $2;
-        if (parseContext->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
-            parseContext->recover();
-        if (parseContext->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
-            parseContext->recover();
+        if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+            context->recover();
+        if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+            context->recover();
     }
     //
     // Only type
     //
     | type_qualifier parameter_qualifier parameter_type_specifier {
         $$ = $3;
-        if (parseContext->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
-            parseContext->recover();
+        if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+            context->recover();
     }
     | parameter_qualifier parameter_type_specifier {
         $$ = $2;
-        if (parseContext->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
-            parseContext->recover();
-        if (parseContext->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
-            parseContext->recover();
+        if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+            context->recover();
+        if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+            context->recover();
     }
     ;
 
@@ -1212,152 +1178,83 @@
         $$ = $1;
         
         if ($$.type.precision == EbpUndefined) {
-            $$.type.precision = parseContext->symbolTable.getDefaultPrecision($1.type.type);
-            if (parseContext->precisionErrorCheck($1.line, $$.type.precision, $1.type.type)) {
-                parseContext->recover();
+            $$.type.precision = context->symbolTable.getDefaultPrecision($1.type.type);
+            if (context->precisionErrorCheck($1.line, $$.type.precision, $1.type.type)) {
+                context->recover();
             }
         }
     }
     | init_declarator_list COMMA IDENTIFIER {
-        $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, parseContext->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line), $3.line);
+        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line), $3.line);
         
-        if (parseContext->structQualifierErrorCheck($3.line, $$.type))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($3.line, $$.type))
+            context->recover();
 
-        if (parseContext->nonInitConstErrorCheck($3.line, *$3.string, $$.type))
-            parseContext->recover();
+        if (context->nonInitConstErrorCheck($3.line, *$3.string, $$.type))
+            context->recover();
 
-        if (parseContext->nonInitErrorCheck($3.line, *$3.string, $$.type))
-            parseContext->recover();
+        if (context->nonInitErrorCheck($3.line, *$3.string, $$.type))
+            context->recover();
     }
     | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
-        if (parseContext->structQualifierErrorCheck($3.line, $1.type))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($3.line, $1.type))
+            context->recover();
 
-        if (parseContext->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
-            parseContext->recover();
+        if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
+            context->recover();
 
         $$ = $1;
 
-        if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
-            parseContext->recover();
+        if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
+            context->recover();
         else {
             $1.type.setArray(true);
             TVariable* variable;
-            if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
-                parseContext->recover();
+            if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+                context->recover();
         }
     }
     | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        if (parseContext->structQualifierErrorCheck($3.line, $1.type))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($3.line, $1.type))
+            context->recover();
 
-        if (parseContext->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
-            parseContext->recover();
+        if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
+            context->recover();
 
         $$ = $1;
 
-        if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
-            parseContext->recover();
+        if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
+            context->recover();
         else {
             int size;
-            if (parseContext->arraySizeErrorCheck($4.line, $5, size))
-                parseContext->recover();
+            if (context->arraySizeErrorCheck($4.line, $5, size))
+                context->recover();
             $1.type.setArray(true, size);
             TVariable* variable;
-            if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
-                parseContext->recover();
+            if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+                context->recover();
             TType type = TType($1.type);
             type.setArraySize(size);
-            $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, parseContext->intermediate.addSymbol(0, *$3.string, type, $3.line), $3.line);
-        }
-    }
-    | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
-        if (parseContext->structQualifierErrorCheck($3.line, $1.type))
-            parseContext->recover();
-
-        $$ = $1;
-
-        TVariable* variable = 0;
-        if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
-            parseContext->recover();
-        else {
-            $1.type.setArray(true, $7->getType().getArraySize());
-            if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
-                parseContext->recover();
-        }
-
-        if (parseContext->extensionErrorCheck($$.line, "GL_3DL_array_objects"))
-            parseContext->recover();
-        else {
-            TIntermNode* intermNode;
-            if (!parseContext->executeInitializer($3.line, *$3.string, $1.type, $7, intermNode, variable)) {
-                //
-                // build the intermediate representation
-                //
-                if (intermNode)
-                    $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, intermNode, $6.line);
-                else
-                    $$.intermAggregate = $1.intermAggregate;
-            } else {
-                parseContext->recover();
-                $$.intermAggregate = 0;
-            }
-        }
-    }
-    | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
-        if (parseContext->structQualifierErrorCheck($3.line, $1.type))
-            parseContext->recover();
-
-        $$ = $1;
-
-        TVariable* variable = 0;
-        if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
-            parseContext->recover();
-        else {
-            int size;
-            if (parseContext->arraySizeErrorCheck($4.line, $5, size))
-                parseContext->recover();
-            $1.type.setArray(true, size);
-            if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
-                parseContext->recover();
-        }
-
-        if (parseContext->extensionErrorCheck($$.line, "GL_3DL_array_objects"))
-            parseContext->recover();
-        else {
-            TIntermNode* intermNode;
-            if (!parseContext->executeInitializer($3.line, *$3.string, $1.type, $8, intermNode, variable)) {
-                //
-                // build the intermediate representation
-                //
-                if (intermNode)
-                    $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, intermNode, $7.line);
-                else
-                    $$.intermAggregate = $1.intermAggregate;
-            } else {
-                parseContext->recover();
-                $$.intermAggregate = 0;
-            }
+            $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(0, *$3.string, type, $3.line), $3.line);
         }
     }
     | init_declarator_list COMMA IDENTIFIER EQUAL initializer {
-        if (parseContext->structQualifierErrorCheck($3.line, $1.type))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($3.line, $1.type))
+            context->recover();
 
         $$ = $1;
 
         TIntermNode* intermNode;
-        if (!parseContext->executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) {
+        if (!context->executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) {
             //
             // build the intermediate representation
             //
             if (intermNode)
-        $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, intermNode, $4.line);
+        $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, $4.line);
             else
                 $$.intermAggregate = $1.intermAggregate;
         } else {
-            parseContext->recover();
+            context->recover();
             $$.intermAggregate = 0;
         }
     }
@@ -1366,88 +1263,88 @@
 single_declaration
     : fully_specified_type {
         $$.type = $1;
-        $$.intermAggregate = parseContext->intermediate.makeAggregate(parseContext->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line);
+        $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line);
     }
     | fully_specified_type IDENTIFIER {
-        $$.intermAggregate = parseContext->intermediate.makeAggregate(parseContext->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
+        $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
         
-        if (parseContext->structQualifierErrorCheck($2.line, $$.type))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($2.line, $$.type))
+            context->recover();
 
-        if (parseContext->nonInitConstErrorCheck($2.line, *$2.string, $$.type))
-            parseContext->recover();
+        if (context->nonInitConstErrorCheck($2.line, *$2.string, $$.type))
+            context->recover();
             
             $$.type = $1;
 
-        if (parseContext->nonInitErrorCheck($2.line, *$2.string, $$.type))
-            parseContext->recover();
+        if (context->nonInitErrorCheck($2.line, *$2.string, $$.type))
+            context->recover();
     }
     | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
-        $$.intermAggregate = parseContext->intermediate.makeAggregate(parseContext->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
+        $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
         
-        if (parseContext->structQualifierErrorCheck($2.line, $1))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($2.line, $1))
+            context->recover();
 
-        if (parseContext->nonInitConstErrorCheck($2.line, *$2.string, $1))
-            parseContext->recover();
+        if (context->nonInitConstErrorCheck($2.line, *$2.string, $1))
+            context->recover();
 
         $$.type = $1;
 
-        if (parseContext->arrayTypeErrorCheck($3.line, $1) || parseContext->arrayQualifierErrorCheck($3.line, $1))
-            parseContext->recover();
+        if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
+            context->recover();
         else {
             $1.setArray(true);
             TVariable* variable;
-            if (parseContext->arrayErrorCheck($3.line, *$2.string, $1, variable))
-                parseContext->recover();
+            if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
+                context->recover();
         }
     }
     | fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
         TType type = TType($1);
         int size;
-        if (parseContext->arraySizeErrorCheck($2.line, $4, size))
-            parseContext->recover();
+        if (context->arraySizeErrorCheck($2.line, $4, size))
+            context->recover();
         type.setArraySize(size);
-        $$.intermAggregate = parseContext->intermediate.makeAggregate(parseContext->intermediate.addSymbol(0, *$2.string, type, $2.line), $2.line);
+        $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, type, $2.line), $2.line);
         
-        if (parseContext->structQualifierErrorCheck($2.line, $1))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($2.line, $1))
+            context->recover();
 
-        if (parseContext->nonInitConstErrorCheck($2.line, *$2.string, $1))
-            parseContext->recover();
+        if (context->nonInitConstErrorCheck($2.line, *$2.string, $1))
+            context->recover();
 
         $$.type = $1;
 
-        if (parseContext->arrayTypeErrorCheck($3.line, $1) || parseContext->arrayQualifierErrorCheck($3.line, $1))
-            parseContext->recover();
+        if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
+            context->recover();
         else {
             int size;
-            if (parseContext->arraySizeErrorCheck($3.line, $4, size))
-                parseContext->recover();
+            if (context->arraySizeErrorCheck($3.line, $4, size))
+                context->recover();
 
             $1.setArray(true, size);
             TVariable* variable;
-            if (parseContext->arrayErrorCheck($3.line, *$2.string, $1, variable))
-                parseContext->recover();
+            if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
+                context->recover();
         }
     }
     | fully_specified_type IDENTIFIER EQUAL initializer {
-        if (parseContext->structQualifierErrorCheck($2.line, $1))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($2.line, $1))
+            context->recover();
 
         $$.type = $1;
 
         TIntermNode* intermNode;
-        if (!parseContext->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
+        if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
         //
         // Build intermediate representation
         //
             if(intermNode)
-                $$.intermAggregate = parseContext->intermediate.makeAggregate(intermNode, $3.line);
+                $$.intermAggregate = context->intermediate.makeAggregate(intermNode, $3.line);
             else
                 $$.intermAggregate = 0;
         } else {
-            parseContext->recover();
+            context->recover();
             $$.intermAggregate = 0;
         }
     }
@@ -1479,14 +1376,14 @@
 //
 //input_or_output
 //    : INPUT {
-//        if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "input"))
-//            parseContext->recover();
+//        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "input"))
+//            context->recover();
 //        UNPACK_ONLY("input", $1.line);
 //        $$.qualifier = EvqInput;
 //    }
 //    | OUTPUT {
-//        if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "output"))
-//            parseContext->recover();
+//        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "output"))
+//            context->recover();
 //        PACK_ONLY("output", $1.line);
 //        $$.qualifier = EvqOutput;
 //    }
@@ -1515,12 +1412,12 @@
 //
 //buffer_declaration
 //    : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
-//        if (parseContext->reservedErrorCheck($2.line, *$2.string, parseContext))
-//            parseContext->recover();
+//        if (context->reservedErrorCheck($2.line, *$2.string, context))
+//            context->recover();
 //        $$.variable = new TVariable($2.string, $1);
-//        if (! parseContext->symbolTable.insert(*$$.variable)) {
-//            parseContext->error($2.line, "redefinition", $$.variable->getName().c_str(), "");
-//            parseContext->recover();
+//        if (! context->symbolTable.insert(*$$.variable)) {
+//            context->error($2.line, "redefinition", $$.variable->getName().c_str(), "");
+//            context->recover();
 //            // don't have to delete $$.variable, the pool pop will take care of it
 //        }
 //    }
@@ -1531,31 +1428,27 @@
         $$ = $1;
 
         if ($1.array) {
-            if (parseContext->extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
-                parseContext->recover();
-                $1.setArray(false);
-            }
+            context->error($1.line, "not supported", "first-class array", "");
+            context->recover();
+            $1.setArray(false);
         }
     }
     | type_qualifier type_specifier  {
-        if ($2.array && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects")) {
-            parseContext->recover();
-            $2.setArray(false);
-        }
-        if ($2.array && parseContext->arrayQualifierErrorCheck($2.line, $1)) {
-            parseContext->recover();
+        if ($2.array) {
+            context->error($2.line, "not supported", "first-class array", "");
+            context->recover();
             $2.setArray(false);
         }
 
         if ($1.qualifier == EvqAttribute &&
             ($2.type == EbtBool || $2.type == EbtInt)) {
-            parseContext->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
-            parseContext->recover();
+            context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
+            context->recover();
         }
         if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
             ($2.type == EbtBool || $2.type == EbtInt)) {
-            parseContext->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
-            parseContext->recover();
+            context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
+            context->recover();
         }
         $$ = $2;
         $$.qualifier = $1.qualifier;
@@ -1568,29 +1461,29 @@
     }
     | ATTRIBUTE {
         VERTEX_ONLY("attribute", $1.line);
-        if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "attribute"))
-            parseContext->recover();
+        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "attribute"))
+            context->recover();
         $$.setBasic(EbtVoid, EvqAttribute, $1.line);
     }
     | VARYING {
-        if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "varying"))
-            parseContext->recover();
-        if (parseContext->language == EShLangVertex)
+        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "varying"))
+            context->recover();
+        if (context->shaderType == SH_VERTEX_SHADER)
             $$.setBasic(EbtVoid, EvqVaryingOut, $1.line);
         else
             $$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
     }
     | INVARIANT VARYING {
-        if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "invariant varying"))
-            parseContext->recover();
-        if (parseContext->language == EShLangVertex)
+        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+            context->recover();
+        if (context->shaderType == SH_VERTEX_SHADER)
             $$.setBasic(EbtVoid, EvqInvariantVaryingOut, $1.line);
         else
             $$.setBasic(EbtVoid, EvqInvariantVaryingIn, $1.line);
     }
     | UNIFORM {
-        if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "uniform"))
-            parseContext->recover();
+        if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "uniform"))
+            context->recover();
         $$.setBasic(EbtVoid, EvqUniform, $1.line);
     }
     ;
@@ -1624,12 +1517,12 @@
     | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
         $$ = $1;
 
-        if (parseContext->arrayTypeErrorCheck($2.line, $1))
-            parseContext->recover();
+        if (context->arrayTypeErrorCheck($2.line, $1))
+            context->recover();
         else {
             int size;
-            if (parseContext->arraySizeErrorCheck($2.line, $3, size))
-                parseContext->recover();
+            if (context->arraySizeErrorCheck($2.line, $3, size))
+                context->recover();
             $$.setArray(true, size);
         }
     }
@@ -1637,103 +1530,103 @@
 
 type_specifier_nonarray
     : VOID_TYPE {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtVoid, qual, $1.line);
     }
     | FLOAT_TYPE {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtFloat, qual, $1.line);
     }
     | INT_TYPE {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtInt, qual, $1.line);
     }
     | BOOL_TYPE {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtBool, qual, $1.line);
     }
 //    | UNSIGNED INT_TYPE {
 //        PACK_UNPACK_ONLY("unsigned", $1.line);
-//        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+//        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
 //        $$.setBasic(EbtInt, qual, $1.line);
 //    }
     | VEC2 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtFloat, qual, $1.line);
         $$.setAggregate(2);
     }
     | VEC3 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtFloat, qual, $1.line);
         $$.setAggregate(3);
     }
     | VEC4 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtFloat, qual, $1.line);
         $$.setAggregate(4);
     }
     | BVEC2 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtBool, qual, $1.line);
         $$.setAggregate(2);
     }
     | BVEC3 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtBool, qual, $1.line);
         $$.setAggregate(3);
     }
     | BVEC4 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtBool, qual, $1.line);
         $$.setAggregate(4);
     }
     | IVEC2 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtInt, qual, $1.line);
         $$.setAggregate(2);
     }
     | IVEC3 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtInt, qual, $1.line);
         $$.setAggregate(3);
     }
     | IVEC4 {
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtInt, qual, $1.line);
         $$.setAggregate(4);
     }
     | MATRIX2 {
         FRAG_VERT_ONLY("mat2", $1.line);
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtFloat, qual, $1.line);
         $$.setAggregate(2, true);
     }
     | MATRIX3 {
         FRAG_VERT_ONLY("mat3", $1.line);
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtFloat, qual, $1.line);
         $$.setAggregate(3, true);
     }
     | MATRIX4 {
         FRAG_VERT_ONLY("mat4", $1.line);
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtFloat, qual, $1.line);
         $$.setAggregate(4, true);
     }
     | SAMPLER2D {
         FRAG_VERT_ONLY("sampler2D", $1.line);
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtSampler2D, qual, $1.line);
     }
     | SAMPLERCUBE {
         FRAG_VERT_ONLY("samplerCube", $1.line);
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtSamplerCube, qual, $1.line);
     }
     | struct_specifier {
         FRAG_VERT_ONLY("struct", $1.line);
         $$ = $1;
-        $$.qualifier = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
     }
     | TYPE_NAME {
         //
@@ -1741,7 +1634,7 @@
         // type.
         //
         TType& structure = static_cast<TVariable*>($1.symbol)->getType();
-        TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
         $$.setBasic(EbtStruct, qual, $1.line);
         $$.userDef = &structure;
     }
@@ -1749,14 +1642,14 @@
 
 struct_specifier
     : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
-        if (parseContext->reservedErrorCheck($2.line, *$2.string))
-            parseContext->recover();
+        if (context->reservedErrorCheck($2.line, *$2.string))
+            context->recover();
 
         TType* structure = new TType($4, *$2.string);
         TVariable* userTypeDef = new TVariable($2.string, *structure, true);
-        if (! parseContext->symbolTable.insert(*userTypeDef)) {
-            parseContext->error($2.line, "redefinition", $2.string->c_str(), "struct");
-            parseContext->recover();
+        if (! context->symbolTable.insert(*userTypeDef)) {
+            context->error($2.line, "redefinition", $2.string->c_str(), "struct");
+            context->recover();
         }
         $$.setBasic(EbtStruct, EvqTemporary, $1.line);
         $$.userDef = structure;
@@ -1777,8 +1670,8 @@
         for (unsigned int i = 0; i < $2->size(); ++i) {
             for (unsigned int j = 0; j < $$->size(); ++j) {
                 if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) {
-                    parseContext->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
-                    parseContext->recover();
+                    context->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
+                    context->recover();
                 }
             }
             $$->push_back((*$2)[i]);
@@ -1790,8 +1683,8 @@
     : type_specifier struct_declarator_list SEMICOLON {
         $$ = $2;
 
-        if (parseContext->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
-            parseContext->recover();
+        if (context->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
+            context->recover();
         }
         for (unsigned int i = 0; i < $$->size(); ++i) {
             //
@@ -1804,8 +1697,8 @@
 
             // don't allow arrays of arrays
             if (type->isArray()) {
-                if (parseContext->arrayTypeErrorCheck($1.line, $1))
-                    parseContext->recover();
+                if (context->arrayTypeErrorCheck($1.line, $1))
+                    context->recover();
             }
             if ($1.array)
                 type->setArraySize($1.arraySize);
@@ -1829,24 +1722,24 @@
 
 struct_declarator
     : IDENTIFIER {
-        if (parseContext->reservedErrorCheck($1.line, *$1.string))
-            parseContext->recover();
+        if (context->reservedErrorCheck($1.line, *$1.string))
+            context->recover();
 
         $$.type = new TType(EbtVoid, EbpUndefined);
         $$.line = $1.line;
         $$.type->setFieldName(*$1.string);
     }
     | IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
-        if (parseContext->reservedErrorCheck($1.line, *$1.string))
-            parseContext->recover();
+        if (context->reservedErrorCheck($1.line, *$1.string))
+            context->recover();
 
         $$.type = new TType(EbtVoid, EbpUndefined);
         $$.line = $1.line;
         $$.type->setFieldName(*$1.string);
 
         int size;
-        if (parseContext->arraySizeErrorCheck($2.line, $3, size))
-            parseContext->recover();
+        if (context->arraySizeErrorCheck($2.line, $3, size))
+            context->recover();
         $$.type->setArraySize(size);
     }
     ;
@@ -1876,7 +1769,7 @@
 
 compound_statement
     : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
-    | LEFT_BRACE { parseContext->symbolTable.push(); } statement_list { parseContext->symbolTable.pop(); } RIGHT_BRACE {
+    | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
         if ($3 != 0)
             $3->setOp(EOpSequence);
         $$ = $3;
@@ -1902,10 +1795,10 @@
 
 statement_list
     : statement {
-        $$ = parseContext->intermediate.makeAggregate($1, 0);
+        $$ = context->intermediate.makeAggregate($1, 0);
     }
     | statement_list statement {
-        $$ = parseContext->intermediate.growAggregate($1, $2, 0);
+        $$ = context->intermediate.growAggregate($1, $2, 0);
     }
     ;
 
@@ -1916,9 +1809,9 @@
 
 selection_statement
     : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
-        if (parseContext->boolErrorCheck($1.line, $3))
-            parseContext->recover();
-        $$ = parseContext->intermediate.addSelection($3, $5, $1.line);
+        if (context->boolErrorCheck($1.line, $3))
+            context->recover();
+        $$ = context->intermediate.addSelection($3, $5, $1.line);
     }
     ;
 
@@ -1939,42 +1832,42 @@
     // In 1996 c++ draft, conditions can include single declarations
     : expression {
         $$ = $1;
-        if (parseContext->boolErrorCheck($1->getLine(), $1))
-            parseContext->recover();
+        if (context->boolErrorCheck($1->getLine(), $1))
+            context->recover();
     }
     | fully_specified_type IDENTIFIER EQUAL initializer {
         TIntermNode* intermNode;
-        if (parseContext->structQualifierErrorCheck($2.line, $1))
-            parseContext->recover();
-        if (parseContext->boolErrorCheck($2.line, $1))
-            parseContext->recover();
+        if (context->structQualifierErrorCheck($2.line, $1))
+            context->recover();
+        if (context->boolErrorCheck($2.line, $1))
+            context->recover();
 
-        if (!parseContext->executeInitializer($2.line, *$2.string, $1, $4, intermNode))
+        if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode))
             $$ = $4;
         else {
-            parseContext->recover();
+            context->recover();
             $$ = 0;
         }
     }
     ;
 
 iteration_statement
-    : WHILE LEFT_PAREN { parseContext->symbolTable.push(); ++parseContext->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
-        parseContext->symbolTable.pop();
-        $$ = parseContext->intermediate.addLoop(0, $6, $4, 0, true, $1.line);
-        --parseContext->loopNestingLevel;
+    : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
+        context->symbolTable.pop();
+        $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line);
+        --context->loopNestingLevel;
     }
-    | DO { ++parseContext->loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
-        if (parseContext->boolErrorCheck($8.line, $6))
-            parseContext->recover();
+    | DO { ++context->loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
+        if (context->boolErrorCheck($8.line, $6))
+            context->recover();
 
-        $$ = parseContext->intermediate.addLoop(0, $3, $6, 0, false, $4.line);
-        --parseContext->loopNestingLevel;
+        $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, $4.line);
+        --context->loopNestingLevel;
     }
-    | FOR LEFT_PAREN { parseContext->symbolTable.push(); ++parseContext->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
-        parseContext->symbolTable.pop();
-        $$ = parseContext->intermediate.addLoop($4, $7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.line);
-        --parseContext->loopNestingLevel;
+    | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
+        context->symbolTable.pop();
+        $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, $1.line);
+        --context->loopNestingLevel;
     }
     ;
 
@@ -2009,40 +1902,40 @@
 
 jump_statement
     : CONTINUE SEMICOLON {
-        if (parseContext->loopNestingLevel <= 0) {
-            parseContext->error($1.line, "continue statement only allowed in loops", "", "");
-            parseContext->recover();
+        if (context->loopNestingLevel <= 0) {
+            context->error($1.line, "continue statement only allowed in loops", "", "");
+            context->recover();
         }
-        $$ = parseContext->intermediate.addBranch(EOpContinue, $1.line);
+        $$ = context->intermediate.addBranch(EOpContinue, $1.line);
     }
     | BREAK SEMICOLON {
-        if (parseContext->loopNestingLevel <= 0) {
-            parseContext->error($1.line, "break statement only allowed in loops", "", "");
-            parseContext->recover();
+        if (context->loopNestingLevel <= 0) {
+            context->error($1.line, "break statement only allowed in loops", "", "");
+            context->recover();
         }
-        $$ = parseContext->intermediate.addBranch(EOpBreak, $1.line);
+        $$ = context->intermediate.addBranch(EOpBreak, $1.line);
     }
     | RETURN SEMICOLON {
-        $$ = parseContext->intermediate.addBranch(EOpReturn, $1.line);
-        if (parseContext->currentFunctionType->getBasicType() != EbtVoid) {
-            parseContext->error($1.line, "non-void function must return a value", "return", "");
-            parseContext->recover();
+        $$ = context->intermediate.addBranch(EOpReturn, $1.line);
+        if (context->currentFunctionType->getBasicType() != EbtVoid) {
+            context->error($1.line, "non-void function must return a value", "return", "");
+            context->recover();
         }
     }
     | RETURN expression SEMICOLON {
-        $$ = parseContext->intermediate.addBranch(EOpReturn, $2, $1.line);
-        parseContext->functionReturnsValue = true;
-        if (parseContext->currentFunctionType->getBasicType() == EbtVoid) {
-            parseContext->error($1.line, "void function cannot return a value", "return", "");
-            parseContext->recover();
-        } else if (*(parseContext->currentFunctionType) != $2->getType()) {
-            parseContext->error($1.line, "function return is not matching type:", "return", "");
-            parseContext->recover();
+        $$ = context->intermediate.addBranch(EOpReturn, $2, $1.line);
+        context->functionReturnsValue = true;
+        if (context->currentFunctionType->getBasicType() == EbtVoid) {
+            context->error($1.line, "void function cannot return a value", "return", "");
+            context->recover();
+        } else if (*(context->currentFunctionType) != $2->getType()) {
+            context->error($1.line, "function return is not matching type:", "return", "");
+            context->recover();
         }
     }
     | DISCARD SEMICOLON {
         FRAG_ONLY("discard", $1.line);
-        $$ = parseContext->intermediate.addBranch(EOpKill, $1.line);
+        $$ = context->intermediate.addBranch(EOpKill, $1.line);
     }
     ;
 
@@ -2051,11 +1944,11 @@
 translation_unit
     : external_declaration {
         $$ = $1;
-        parseContext->treeRoot = $$;
+        context->treeRoot = $$;
     }
     | translation_unit external_declaration {
-        $$ = parseContext->intermediate.growAggregate($1, $2, 0);
-        parseContext->treeRoot = $$;
+        $$ = context->intermediate.growAggregate($1, $2, 0);
+        context->treeRoot = $$;
     }
     ;
 
@@ -2070,8 +1963,8 @@
 
 function_definition
     : function_prototype {
-        TFunction& function = *($1.function);
-        TFunction* prevDec = static_cast<TFunction*>(parseContext->symbolTable.find(function.getMangledName()));
+        TFunction* function = $1.function;
+        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
         //
         // Note:  'prevDec' could be 'function' if this is the first time we've seen function
         // as it would have just been put in the symbol table.  Otherwise, we're looking up
@@ -2081,35 +1974,35 @@
             //
             // Then this function already has a body.
             //
-            parseContext->error($1.line, "function already has a body", function.getName().c_str(), "");
-            parseContext->recover();
+            context->error($1.line, "function already has a body", function->getName().c_str(), "");
+            context->recover();
         }
         prevDec->setDefined();
 
         //
         // Raise error message if main function takes any parameters or return anything other than void
         //
-        if (function.getName() == "main") {
-            if (function.getParamCount() > 0) {
-                parseContext->error($1.line, "function cannot take any parameter(s)", function.getName().c_str(), "");
-                parseContext->recover();
+        if (function->getName() == "main") {
+            if (function->getParamCount() > 0) {
+                context->error($1.line, "function cannot take any parameter(s)", function->getName().c_str(), "");
+                context->recover();
             }
-            if (function.getReturnType().getBasicType() != EbtVoid) {
-                parseContext->error($1.line, "", function.getReturnType().getBasicString(), "main function cannot return a value");
-                parseContext->recover();
+            if (function->getReturnType().getBasicType() != EbtVoid) {
+                context->error($1.line, "", function->getReturnType().getBasicString(), "main function cannot return a value");
+                context->recover();
             }
         }
 
         //
         // New symbol table scope for body of function plus its arguments
         //
-        parseContext->symbolTable.push();
+        context->symbolTable.push();
 
         //
         // Remember the return type for later checking for RETURN statements.
         //
-        parseContext->currentFunctionType = &(prevDec->getReturnType());
-        parseContext->functionReturnsValue = false;
+        context->currentFunctionType = &(prevDec->getReturnType());
+        context->functionReturnsValue = false;
 
         //
         // Insert parameters into the symbol table.
@@ -2120,59 +2013,60 @@
         // knows where to find parameters.
         //
         TIntermAggregate* paramNodes = new TIntermAggregate;
-        for (int i = 0; i < function.getParamCount(); i++) {
-            TParameter& param = function[i];
+        for (int i = 0; i < function->getParamCount(); i++) {
+            const TParameter& param = function->getParam(i);
             if (param.name != 0) {
                 TVariable *variable = new TVariable(param.name, *param.type);
                 //
                 // Insert the parameters with name in the symbol table.
                 //
-                if (! parseContext->symbolTable.insert(*variable)) {
-                    parseContext->error($1.line, "redefinition", variable->getName().c_str(), "");
-                    parseContext->recover();
+                if (! context->symbolTable.insert(*variable)) {
+                    context->error($1.line, "redefinition", variable->getName().c_str(), "");
+                    context->recover();
                     delete variable;
                 }
-                //
-                // Transfer ownership of name pointer to symbol table.
-                //
-                param.name = 0;
 
                 //
                 // Add the parameter to the HIL
                 //
-                paramNodes = parseContext->intermediate.growAggregate(
+                paramNodes = context->intermediate.growAggregate(
                                                paramNodes,
-                                               parseContext->intermediate.addSymbol(variable->getUniqueId(),
+                                               context->intermediate.addSymbol(variable->getUniqueId(),
                                                                        variable->getName(),
                                                                        variable->getType(), $1.line),
                                                $1.line);
             } else {
-                paramNodes = parseContext->intermediate.growAggregate(paramNodes, parseContext->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
+                paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
             }
         }
-        parseContext->intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line);
+        context->intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line);
         $1.intermAggregate = paramNodes;
-        parseContext->loopNestingLevel = 0;
+        context->loopNestingLevel = 0;
     }
     compound_statement_no_new_scope {
         //?? Check that all paths return a value if return type != void ?
         //   May be best done as post process phase on intermediate code
-        if (parseContext->currentFunctionType->getBasicType() != EbtVoid && ! parseContext->functionReturnsValue) {
-            parseContext->error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
-            parseContext->recover();
+        if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
+            context->error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
+            context->recover();
         }
-        parseContext->symbolTable.pop();
-        $$ = parseContext->intermediate.growAggregate($1.intermAggregate, $3, 0);
-        parseContext->intermediate.setAggregateOperator($$, EOpFunction, $1.line);
+        context->symbolTable.pop();
+        $$ = context->intermediate.growAggregate($1.intermAggregate, $3, 0);
+        context->intermediate.setAggregateOperator($$, EOpFunction, $1.line);
         $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
         $$->getAsAggregate()->setType($1.function->getReturnType());
 
         // store the pragma information for debug and optimize and other vendor specific
         // information. This information can be queried from the parse tree
-        $$->getAsAggregate()->setOptimize(parseContext->contextPragma.optimize);
-        $$->getAsAggregate()->setDebug(parseContext->contextPragma.debug);
-        $$->getAsAggregate()->addToPragmaTable(parseContext->contextPragma.pragmaTable);
+        $$->getAsAggregate()->setOptimize(context->contextPragma.optimize);
+        $$->getAsAggregate()->setDebug(context->contextPragma.debug);
+        $$->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
     }
     ;
 
 %%
+
+int glslang_parse(TParseContext* context) {
+    return yyparse(context);
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp b/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp
new file mode 100644
index 0000000..9d5f53f
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp
@@ -0,0 +1,3186 @@
+#line 17 "compiler/glslang.l"
+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// This file is auto-generated by generate_glslang_lexer.sh. DO NOT EDIT!
+
+
+
+#line 13 "compiler/glslang_lex.cpp"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif	/* defined (__STDC__) */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+   are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                int yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = yyg->yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+                          ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void yypop_buffer_state (yyscan_t yyscanner );
+
+static void yyensure_buffer_stack (yyscan_t yyscanner );
+static void yy_load_buffer_state (yyscan_t yyscanner );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (yyscanner); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (yyscanner); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yyg->yytext_ptr = yy_bp; \
+	yyleng = (size_t) (yy_cp - yy_bp); \
+	yyg->yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 145
+#define YY_END_OF_BUFFER 146
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[411] =
+    {   0,
+        0,    0,    0,    0,    0,    0,  146,  144,  143,  143,
+      128,  134,  139,  123,  124,  132,  131,  120,  129,  127,
+      133,   92,   92,  121,  117,  135,  122,  136,  140,   88,
+      125,  126,  138,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,  118,  137,  119,  130,    3,    4,    3,
+      142,  145,  141,  114,  100,  119,  108,  103,   98,  106,
+       96,  107,   97,   95,    2,    1,   99,   94,   90,   91,
+        0,    0,   92,  126,  118,  125,  115,  111,  113,  112,
+      116,   88,  104,  110,   88,   88,   88,   88,   88,   88,
+
+       88,   88,   88,   88,   17,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   20,   22,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,  105,  109,    5,  141,
+        0,    1,   94,    0,    0,   93,   89,  101,  102,   48,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   18,   88,   88,
+       88,   88,   88,   88,   88,   88,   26,   88,   88,   88,
+       88,   88,   88,   88,   88,   23,   88,   88,   88,   88,
+
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,    0,   95,
+        0,   94,   88,   28,   88,   88,   85,   88,   88,   88,
+       88,   88,   88,   88,   21,   51,   88,   88,   88,   88,
+       88,   56,   70,   88,   88,   88,   88,   88,   88,   88,
+       88,   67,    9,   33,   34,   35,   88,   88,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
+       88,   54,   29,   88,   88,   88,   88,   88,   88,   36,
+       37,   38,   27,   88,   88,   88,   15,   42,   43,   44,
+       49,   12,   88,   88,   88,   88,   81,   82,   83,   88,
+
+       30,   71,   25,   78,   79,   80,    7,   75,   76,   77,
+       88,   24,   73,   88,   88,   39,   40,   41,   88,   88,
+       88,   88,   88,   88,   88,   88,   88,   68,   88,   88,
+       88,   88,   88,   88,   88,   50,   88,   87,   88,   88,
+       19,   88,   88,   88,   88,   69,   64,   59,   88,   88,
+       88,   88,   88,   74,   55,   88,   62,   32,   88,   84,
+       63,   47,   57,   88,   88,   88,   88,   88,   88,   88,
+       88,   58,   31,   88,   88,   88,    8,   88,   88,   88,
+       88,   88,   52,   13,   88,   14,   88,   88,   16,   65,
+       88,   88,   88,   60,   88,   88,   88,   53,   72,   61,
+
+       11,   66,    6,   86,   10,   45,   88,   88,   46,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    1,    1,    1,    5,    6,    1,    7,
+        8,    9,   10,   11,   12,   13,   14,   15,   16,   17,
+       18,   19,   16,   16,   16,   20,   20,   21,   22,   23,
+       24,   25,   26,    1,   27,   27,   28,   29,   30,   27,
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   32,   31,   31,
+       33,    1,   34,   35,   31,    1,   36,   37,   38,   39,
+
+       40,   41,   42,   43,   44,   31,   45,   46,   47,   48,
+       49,   50,   31,   51,   52,   53,   54,   55,   56,   57,
+       58,   59,   60,   61,   62,   63,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[64] =
+    {   0,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    3,    3,    3,    3,    3,    3,
+        1,    1,    1,    1,    1,    1,    3,    3,    3,    3,
+        4,    4,    1,    1,    1,    3,    3,    3,    3,    3,
+        3,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    1,
+        1,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[416] =
+    {   0,
+        0,    0,   61,   62,   71,    0,  606,  607,  607,  607,
+      581,   42,  129,  607,  607,  580,  126,  607,  125,  123,
+      137,  149,  157,  578,  607,  175,  578,   44,  607,    0,
+      607,  607,  120,   95,  103,  142,  146,  136,  156,  552,
+      168,  162,  551,  120,  158,  545,  173,  558,  172,  178,
+      111,  186,  554,  607,  159,  607,  607,  607,  607,  582,
+      607,  607,    0,  607,  607,  607,  607,  607,  607,  607,
+      607,  607,  607,  222,  607,    0,  607,  228,  254,  262,
+      281,    0,  290,  607,  607,  607,  571,  607,  607,  607,
+      570,    0,  607,  607,  546,  539,  542,  550,  549,  536,
+
+      551,  538,  544,  532,  529,  542,  529,  526,  526,  532,
+      520,  527,  524,  534,  520,  526,  529,  530,    0,  204,
+      529,  207,  515,  528,  519,  521,  511,  525,  522,  524,
+      507,  512,  509,  498,  183,  512,  508,  510,  499,  502,
+      212,  507,  499,  511,  186,  504,  607,  607,  607,    0,
+      306,    0,  316,  332,  270,  342,    0,  607,  607,    0,
+      496,  500,  509,  506,  490,  490,  161,  505,  502,  502,
+      500,  497,  489,  495,  482,  493,  496,    0,  493,  481,
+      488,  485,  489,  482,  471,  470,  483,  486,  483,  478,
+      469,  294,  474,  477,  468,  465,  469,  475,  466,  457,
+
+      460,  458,  468,  454,  452,  452,  454,  451,  462,  461,
+      278,  456,  451,  440,  320,  458,  460,  449,  348,  354,
+      360,  366,  450,    0,  448,  336,    0,  440,  438,  446,
+      435,  452,  441,  370,    0,    0,  435,  445,  445,  430,
+      373,    0,    0,  432,  376,  433,  427,  426,  427,  426,
+      379,    0,    0,    0,    0,    0,  422,  423,  428,  419,
+      432,  427,  426,  418,  422,  414,  417,  421,  426,  425,
+      416,    0,    0,  422,  411,  411,  416,  415,  412,    0,
+        0,    0,    0,  402,  414,  416,    0,    0,    0,    0,
+        0,    0,  404,  405,  399,  409,    0,    0,    0,  400,
+
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      407,    0,    0,  405,  401,    0,    0,    0,  397,  393,
+      398,  388,  401,  387,  400,  389,  396,    0,  394,  396,
+      380,  389,  395,  390,  378,    0,  380,    0,  379,  382,
+        0,  371,  370,  370,  383,    0,  385,    0,  384,  383,
+      368,  381,  368,    0,    0,  371,    0,    0,  363,    0,
+        0,    0,    0,  360,  371,  364,  368,  303,  297,  288,
+      300,    0,    0,  283,  290,  269,    0,  277,  274,  255,
+      232,  255,    0,    0,  244,    0,  236,  226,    0,    0,
+      225,  208,  211,    0,  185,  202,  131,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,  134,  117,    0,  607,
+      398,  400,  402,  406,  142
+    } ;
+
+static yyconst flex_int16_t yy_def[416] =
+    {   0,
+      410,    1,  411,  411,  410,    5,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  412,
+      410,  410,  410,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  413,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  414,  410,  410,  410,  410,
+      410,  415,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  412,  410,  410,  412,  412,  412,  412,  412,  412,
+
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  410,  410,  410,  413,
+      410,  414,  410,  410,  410,  410,  415,  410,  410,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  410,  410,
+      410,  410,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,
+
+      412,  412,  412,  412,  412,  412,  412,  412,  412,    0,
+      410,  410,  410,  410,  410
+    } ;
+
+static yyconst flex_int16_t yy_nxt[671] =
+    {   0,
+        8,    9,   10,   11,   12,   13,   14,   15,   16,   17,
+       18,   19,   20,   21,   22,   23,   23,   23,   23,   23,
+       24,   25,   26,   27,   28,   29,   30,   30,   30,   30,
+       30,   30,   31,   32,   33,   34,   35,   36,   37,   38,
+       39,   40,   41,   42,   30,   43,   44,   45,   46,   47,
+       48,   49,   50,   51,   52,   53,   30,   30,   30,   54,
+       55,   56,   57,   59,   59,   65,   66,   90,   91,   60,
+       60,    8,   61,   62,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    8,    8,    8,    8,   63,   63,   63,
+
+       63,   63,   63,    8,    8,    8,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+        8,    8,    8,    8,   67,   70,   72,   74,   74,   74,
+       74,   74,   74,   93,  157,   75,   95,   96,   73,   71,
+       76,   97,   68,   98,   94,  123,  409,   99,  141,  124,
+       77,   78,  142,   79,   79,   79,   79,   79,   80,   78,
+      408,   83,   83,   83,   83,   83,   83,  100,   81,   85,
+       82,  107,  147,  108,  407,  103,   81,  101,   81,  104,
+      102,  110,  109,  125,  105,   86,   81,   87,   88,  111,
+
+      106,  112,  119,  116,  113,   82,  126,  132,  128,  120,
+      114,  117,  229,  230,  133,  134,  121,  137,  204,  148,
+      138,  143,  118,  129,  135,  144,  130,  136,  139,  216,
+      406,  217,  405,  205,  145,  140,   74,   74,   74,   74,
+       74,   74,  153,  153,  153,  153,  153,  153,  396,  184,
+      404,  151,  185,  186,  190,  211,  187,  154,  188,  397,
+      403,  151,  191,  212,  402,  401,   78,  154,   79,   79,
+       79,   79,   79,   80,   78,  400,   80,   80,   80,   80,
+       80,   80,  399,   81,  156,  156,  156,  156,  156,  156,
+      155,   81,  155,   81,  398,  156,  156,  156,  156,  156,
+
+      156,   81,   78,  395,   83,   83,   83,   83,   83,   83,
+      254,  255,  256,  394,  393,  219,  392,  219,  275,   81,
+      220,  220,  220,  220,  220,  220,  276,  391,  390,   81,
+      153,  153,  153,  153,  153,  153,  280,  281,  282,  389,
+      388,  221,  387,  221,  386,  154,  222,  222,  222,  222,
+      222,  222,  288,  289,  290,  154,  156,  156,  156,  156,
+      156,  156,  220,  220,  220,  220,  220,  220,  220,  220,
+      220,  220,  220,  220,  222,  222,  222,  222,  222,  222,
+      222,  222,  222,  222,  222,  222,  297,  298,  299,  304,
+      305,  306,  308,  309,  310,  316,  317,  318,   58,   58,
+
+       58,   58,   92,   92,  150,  150,  152,  385,  152,  152,
+      384,  383,  382,  381,  380,  379,  378,  377,  376,  375,
+      374,  373,  372,  371,  370,  369,  368,  367,  366,  365,
+      364,  363,  362,  361,  360,  359,  358,  357,  356,  355,
+      354,  353,  352,  351,  350,  349,  348,  347,  346,  345,
+      344,  343,  342,  341,  340,  339,  338,  337,  336,  335,
+      334,  333,  332,  331,  330,  329,  328,  327,  326,  325,
+      324,  323,  322,  321,  320,  319,  315,  314,  313,  312,
+      311,  307,  303,  302,  301,  300,  296,  295,  294,  293,
+      292,  291,  287,  286,  285,  284,  283,  279,  278,  277,
+
+      274,  273,  272,  271,  270,  269,  268,  267,  266,  265,
+      264,  263,  262,  261,  260,  259,  258,  257,  253,  252,
+      251,  250,  249,  248,  247,  246,  245,  244,  243,  242,
+      241,  240,  239,  238,  237,  236,  235,  234,  233,  232,
+      231,  228,  227,  226,  225,  224,  223,  218,  215,  214,
+      213,  210,  209,  208,  207,  206,  203,  202,  201,  200,
+      199,  198,  197,  196,  195,  194,  193,  192,  189,  183,
+      182,  181,  180,  179,  178,  177,  176,  175,  174,  173,
+      172,  171,  170,  169,  168,  167,  166,  165,  164,  163,
+      162,  161,  160,  159,  158,  149,  146,  131,  127,  122,
+
+      115,   89,   84,   69,   64,  410,    7,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410
+    } ;
+
+static yyconst flex_int16_t yy_chk[671] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    3,    4,   12,   12,   28,   28,    3,
+        4,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,   13,   17,   19,   20,   20,   20,
+       20,   20,   20,   33,  415,   21,   34,   34,   19,   17,
+       21,   35,   13,   35,   33,   44,  408,   35,   51,   44,
+       21,   22,   51,   22,   22,   22,   22,   22,   22,   23,
+      407,   23,   23,   23,   23,   23,   23,   36,   22,   26,
+       22,   38,   55,   38,  397,   37,   23,   36,   22,   37,
+       36,   39,   38,   45,   37,   26,   23,   26,   26,   39,
+
+       37,   39,   42,   41,   39,   22,   45,   49,   47,   42,
+       39,   41,  167,  167,   49,   49,   42,   50,  135,   55,
+       50,   52,   41,   47,   49,   52,   47,   49,   50,  145,
+      396,  145,  395,  135,   52,   50,   74,   74,   74,   74,
+       74,   74,   78,   78,   78,   78,   78,   78,  381,  120,
+      393,   74,  120,  120,  122,  141,  120,   78,  120,  381,
+      392,   74,  122,  141,  391,  388,   79,   78,   79,   79,
+       79,   79,   79,   79,   80,  387,   80,   80,   80,   80,
+       80,   80,  385,   79,  155,  155,  155,  155,  155,  155,
+       81,   80,   81,   79,  382,   81,   81,   81,   81,   81,
+
+       81,   80,   83,  380,   83,   83,   83,   83,   83,   83,
+      192,  192,  192,  379,  378,  151,  376,  151,  211,   83,
+      151,  151,  151,  151,  151,  151,  211,  375,  374,   83,
+      153,  153,  153,  153,  153,  153,  215,  215,  215,  371,
+      370,  154,  369,  154,  368,  153,  154,  154,  154,  154,
+      154,  154,  226,  226,  226,  153,  156,  156,  156,  156,
+      156,  156,  219,  219,  219,  219,  219,  219,  220,  220,
+      220,  220,  220,  220,  221,  221,  221,  221,  221,  221,
+      222,  222,  222,  222,  222,  222,  234,  234,  234,  241,
+      241,  241,  245,  245,  245,  251,  251,  251,  411,  411,
+
+      411,  411,  412,  412,  413,  413,  414,  367,  414,  414,
+      366,  365,  364,  359,  356,  353,  352,  351,  350,  349,
+      347,  345,  344,  343,  342,  340,  339,  337,  335,  334,
+      333,  332,  331,  330,  329,  327,  326,  325,  324,  323,
+      322,  321,  320,  319,  315,  314,  311,  300,  296,  295,
+      294,  293,  286,  285,  284,  279,  278,  277,  276,  275,
+      274,  271,  270,  269,  268,  267,  266,  265,  264,  263,
+      262,  261,  260,  259,  258,  257,  250,  249,  248,  247,
+      246,  244,  240,  239,  238,  237,  233,  232,  231,  230,
+      229,  228,  225,  223,  218,  217,  216,  214,  213,  212,
+
+      210,  209,  208,  207,  206,  205,  204,  203,  202,  201,
+      200,  199,  198,  197,  196,  195,  194,  193,  191,  190,
+      189,  188,  187,  186,  185,  184,  183,  182,  181,  180,
+      179,  177,  176,  175,  174,  173,  172,  171,  170,  169,
+      168,  166,  165,  164,  163,  162,  161,  146,  144,  143,
+      142,  140,  139,  138,  137,  136,  134,  133,  132,  131,
+      130,  129,  128,  127,  126,  125,  124,  123,  121,  118,
+      117,  116,  115,  114,  113,  112,  111,  110,  109,  108,
+      107,  106,  105,  104,  103,  102,  101,  100,   99,   98,
+       97,   96,   95,   91,   87,   60,   53,   48,   46,   43,
+
+       40,   27,   24,   16,   11,    7,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  410,  410,  410,  410,  410
+    } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[146] =
+    {   0,
+0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 0, 0,     };
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+/*
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+This file contains the Lex specification for GLSL ES.
+Based on ANSI C grammar, Lex specification:
+http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
+
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_lexer.sh,
+WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
+*/
+
+#include "compiler/glslang.h"
+#include "compiler/ParseHelper.h"
+#include "compiler/util.h"
+#include "glslang_tab.h"
+
+/* windows only pragma */
+#ifdef _MSC_VER
+#pragma warning(disable : 4102)
+#endif
+
+#define YY_USER_ACTION yylval->lex.line = yylineno;
+#define YY_INPUT(buf, result, max_size) \
+    result = string_input(buf, max_size, yyscanner);
+
+static int string_input(char* buf, int max_size, yyscan_t yyscanner);
+static int check_type(yyscan_t yyscanner);
+static int reserved_word(yyscan_t yyscanner);
+
+#define INITIAL 0
+#define COMMENT 1
+#define FIELDS 2
+
+#define YY_EXTRA_TYPE TParseContext*
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+    {
+
+    /* User-defined. Not touched by flex. */
+    YY_EXTRA_TYPE yyextra_r;
+
+    /* The rest are the same as the globals declared in the non-reentrant scanner. */
+    FILE *yyin_r, *yyout_r;
+    size_t yy_buffer_stack_top; /**< index of top of stack. */
+    size_t yy_buffer_stack_max; /**< capacity of stack. */
+    YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+    char yy_hold_char;
+    int yy_n_chars;
+    int yyleng_r;
+    char *yy_c_buf_p;
+    int yy_init;
+    int yy_start;
+    int yy_did_buffer_switch_on_eof;
+    int yy_start_stack_ptr;
+    int yy_start_stack_depth;
+    int *yy_start_stack;
+    yy_state_type yy_last_accepting_state;
+    char* yy_last_accepting_cpos;
+
+    int yylineno_r;
+    int yy_flex_debug_r;
+
+    char *yytext_r;
+    int yy_more_flag;
+    int yy_more_len;
+
+    YYSTYPE * yylval_r;
+
+    }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+    /* This must go here because YYSTYPE and YYLTYPE are included
+     * from bison output in section 1.*/
+    #    define yylval yyg->yylval_r
+    
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (yyscan_t yyscanner );
+
+int yyget_debug (yyscan_t yyscanner );
+
+void yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *yyget_in (yyscan_t yyscanner );
+
+void yyset_in  (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *yyget_out (yyscan_t yyscanner );
+
+void yyset_out  (FILE * out_str ,yyscan_t yyscanner );
+
+int yyget_leng (yyscan_t yyscanner );
+
+char *yyget_text (yyscan_t yyscanner );
+
+int yyget_lineno (yyscan_t yyscanner );
+
+void yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * yyget_lval (yyscan_t yyscanner );
+
+void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (yyscan_t yyscanner );
+#else
+extern int yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+    static void yy_push_state (int new_state ,yyscan_t yyscanner);
+    
+    static void yy_pop_state (yyscan_t yyscanner );
+    
+    static int yy_top_state (yyscan_t yyscanner );
+    
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		int n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(yyin); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex \
+               (YYSTYPE * yylval_param ,yyscan_t yyscanner);
+
+#define YY_DECL int yylex \
+               (YYSTYPE * yylval_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    TParseContext* context = yyextra;
+
+    /* Single-line comments */
+
+    yylval = yylval_param;
+
+	if ( !yyg->yy_init )
+		{
+		yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yyg->yy_start )
+			yyg->yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			yyensure_buffer_stack (yyscanner);
+			YY_CURRENT_BUFFER_LVALUE =
+				yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+		}
+
+		yy_load_buffer_state(yyscanner );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = yyg->yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yyg->yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yyg->yy_start;
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yyg->yy_last_accepting_state = yy_current_state;
+				yyg->yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 411 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_current_state != 410 );
+		yy_cp = yyg->yy_last_accepting_cpos;
+		yy_current_state = yyg->yy_last_accepting_state;
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+
+		YY_DO_BEFORE_ACTION;
+
+		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+			{
+			int yyl;
+			for ( yyl = 0; yyl < yyleng; ++yyl )
+				if ( yytext[yyl] == '\n' )
+					   
+    do{ yylineno++;
+        yycolumn=0;
+    }while(0)
+;
+			}
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yyg->yy_hold_char;
+			yy_cp = yyg->yy_last_accepting_cpos;
+			yy_current_state = yyg->yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+;
+	YY_BREAK
+/* Multi-line comments */
+case 2:
+YY_RULE_SETUP
+{ yy_push_state(COMMENT, yyscanner); }
+	YY_BREAK
+case 3:
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+{ yy_pop_state(yyscanner); }
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+{ return(INVARIANT); }
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+{ return(HIGH_PRECISION); }
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+{ return(MEDIUM_PRECISION); }
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+{ return(LOW_PRECISION); }
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+{ return(PRECISION); }
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+{ return(ATTRIBUTE); }
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+{ return(CONST_QUAL); }
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+{ return(UNIFORM); }
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+{ return(VARYING); }
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+{ return(BREAK); }
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+{ return(CONTINUE); }
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+{ return(DO); }
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+{ return(FOR); }
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+{ return(WHILE); }
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+{ return(IF); }
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+{ return(ELSE); }
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+{ return(IN_QUAL); }
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+{ return(OUT_QUAL); }
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+{ return(INOUT_QUAL); }
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(FLOAT_TYPE); }
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(INT_TYPE); }
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(VOID_TYPE); }
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(BOOL_TYPE); }
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+{ yylval->lex.b = true;  return(BOOLCONSTANT); }
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+{ yylval->lex.b = false; return(BOOLCONSTANT); }
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+{ return(DISCARD); }
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+{ return(RETURN); }
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(MATRIX2); }
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(MATRIX3); }
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(MATRIX4); }
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (VEC2); }
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (VEC3); }
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (VEC4); }
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (IVEC2); }
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (IVEC3); }
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (IVEC4); }
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (BVEC2); }
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (BVEC3); }
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (BVEC4); }
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return SAMPLER2D; }
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return SAMPLERCUBE; }
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(STRUCT); }
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 57:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 61:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 62:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 63:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 64:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 67:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 68:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 69:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 70:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 71:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 72:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 73:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 74:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 75:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 76:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 77:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 78:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 79:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 80:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 81:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 82:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 83:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 84:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 85:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 86:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 87:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+	YY_BREAK
+case 88:
+YY_RULE_SETUP
+{
+   yylval->lex.string = NewPoolTString(yytext); 
+   return check_type(yyscanner);
+}
+	YY_BREAK
+case 89:
+YY_RULE_SETUP
+{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+	YY_BREAK
+case 90:
+YY_RULE_SETUP
+{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+	YY_BREAK
+case 91:
+YY_RULE_SETUP
+{ context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;}
+	YY_BREAK
+case 92:
+YY_RULE_SETUP
+{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+	YY_BREAK
+case 93:
+YY_RULE_SETUP
+{ yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+	YY_BREAK
+case 94:
+YY_RULE_SETUP
+{ yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+	YY_BREAK
+case 95:
+YY_RULE_SETUP
+{ yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+	YY_BREAK
+case 96:
+YY_RULE_SETUP
+{  return(ADD_ASSIGN); }
+	YY_BREAK
+case 97:
+YY_RULE_SETUP
+{  return(SUB_ASSIGN); }
+	YY_BREAK
+case 98:
+YY_RULE_SETUP
+{  return(MUL_ASSIGN); }
+	YY_BREAK
+case 99:
+YY_RULE_SETUP
+{  return(DIV_ASSIGN); }
+	YY_BREAK
+case 100:
+YY_RULE_SETUP
+{  return(MOD_ASSIGN); }
+	YY_BREAK
+case 101:
+YY_RULE_SETUP
+{  return(LEFT_ASSIGN); }
+	YY_BREAK
+case 102:
+YY_RULE_SETUP
+{  return(RIGHT_ASSIGN); }
+	YY_BREAK
+case 103:
+YY_RULE_SETUP
+{  return(AND_ASSIGN); }
+	YY_BREAK
+case 104:
+YY_RULE_SETUP
+{  return(XOR_ASSIGN); }
+	YY_BREAK
+case 105:
+YY_RULE_SETUP
+{  return(OR_ASSIGN); }
+	YY_BREAK
+case 106:
+YY_RULE_SETUP
+{  return(INC_OP); }
+	YY_BREAK
+case 107:
+YY_RULE_SETUP
+{  return(DEC_OP); }
+	YY_BREAK
+case 108:
+YY_RULE_SETUP
+{  return(AND_OP); }
+	YY_BREAK
+case 109:
+YY_RULE_SETUP
+{  return(OR_OP); }
+	YY_BREAK
+case 110:
+YY_RULE_SETUP
+{  return(XOR_OP); }
+	YY_BREAK
+case 111:
+YY_RULE_SETUP
+{  return(LE_OP); }
+	YY_BREAK
+case 112:
+YY_RULE_SETUP
+{  return(GE_OP); }
+	YY_BREAK
+case 113:
+YY_RULE_SETUP
+{  return(EQ_OP); }
+	YY_BREAK
+case 114:
+YY_RULE_SETUP
+{  return(NE_OP); }
+	YY_BREAK
+case 115:
+YY_RULE_SETUP
+{  return(LEFT_OP); }
+	YY_BREAK
+case 116:
+YY_RULE_SETUP
+{  return(RIGHT_OP); }
+	YY_BREAK
+case 117:
+YY_RULE_SETUP
+{ context->lexAfterType = false; return(SEMICOLON); }
+	YY_BREAK
+case 118:
+YY_RULE_SETUP
+{ context->lexAfterType = false; return(LEFT_BRACE); }
+	YY_BREAK
+case 119:
+YY_RULE_SETUP
+{ return(RIGHT_BRACE); }
+	YY_BREAK
+case 120:
+YY_RULE_SETUP
+{ if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
+	YY_BREAK
+case 121:
+YY_RULE_SETUP
+{ return(COLON); }
+	YY_BREAK
+case 122:
+YY_RULE_SETUP
+{ context->lexAfterType = false; return(EQUAL); }
+	YY_BREAK
+case 123:
+YY_RULE_SETUP
+{ context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
+	YY_BREAK
+case 124:
+YY_RULE_SETUP
+{ context->inTypeParen = false; return(RIGHT_PAREN); }
+	YY_BREAK
+case 125:
+YY_RULE_SETUP
+{ return(LEFT_BRACKET); }
+	YY_BREAK
+case 126:
+YY_RULE_SETUP
+{ return(RIGHT_BRACKET); }
+	YY_BREAK
+case 127:
+YY_RULE_SETUP
+{ BEGIN(FIELDS);  return(DOT); }
+	YY_BREAK
+case 128:
+YY_RULE_SETUP
+{ return(BANG); }
+	YY_BREAK
+case 129:
+YY_RULE_SETUP
+{ return(DASH); }
+	YY_BREAK
+case 130:
+YY_RULE_SETUP
+{ return(TILDE); }
+	YY_BREAK
+case 131:
+YY_RULE_SETUP
+{ return(PLUS); }
+	YY_BREAK
+case 132:
+YY_RULE_SETUP
+{ return(STAR); }
+	YY_BREAK
+case 133:
+YY_RULE_SETUP
+{ return(SLASH); }
+	YY_BREAK
+case 134:
+YY_RULE_SETUP
+{ return(PERCENT); }
+	YY_BREAK
+case 135:
+YY_RULE_SETUP
+{ return(LEFT_ANGLE); }
+	YY_BREAK
+case 136:
+YY_RULE_SETUP
+{ return(RIGHT_ANGLE); }
+	YY_BREAK
+case 137:
+YY_RULE_SETUP
+{ return(VERTICAL_BAR); }
+	YY_BREAK
+case 138:
+YY_RULE_SETUP
+{ return(CARET); }
+	YY_BREAK
+case 139:
+YY_RULE_SETUP
+{ return(AMPERSAND); }
+	YY_BREAK
+case 140:
+YY_RULE_SETUP
+{ return(QUESTION); }
+	YY_BREAK
+case 141:
+YY_RULE_SETUP
+{ 
+    BEGIN(INITIAL);
+    yylval->lex.string = NewPoolTString(yytext); 
+    return FIELD_SELECTION;
+}
+	YY_BREAK
+case 142:
+YY_RULE_SETUP
+{}
+	YY_BREAK
+case 143:
+/* rule 143 can match eol */
+YY_RULE_SETUP
+{  }
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(COMMENT):
+case YY_STATE_EOF(FIELDS):
+{ context->AfterEOF = true; yyterminate(); }
+	YY_BREAK
+case 144:
+YY_RULE_SETUP
+{ context->warning(yylineno, "Unknown char", yytext, ""); return 0; }
+	YY_BREAK
+case 145:
+YY_RULE_SETUP
+ECHO;
+	YY_BREAK
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yyg->yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state( yyscanner );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+			yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yyg->yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yyg->yy_last_accepting_cpos;
+				yy_current_state = yyg->yy_last_accepting_state;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer( yyscanner ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yyg->yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap(yyscanner ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yyg->yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yyg->yy_c_buf_p =
+					yyg->yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state( yyscanner );
+
+				yy_cp = yyg->yy_c_buf_p;
+				yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yyg->yy_c_buf_p =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+				yy_current_state = yy_get_previous_state( yyscanner );
+
+				yy_cp = yyg->yy_c_buf_p;
+				yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = yyg->yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			yyg->yy_n_chars, (size_t) num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+		}
+
+	if ( yyg->yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart(yyin  ,yyscanner);
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+	}
+
+	yyg->yy_n_chars += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	yy_current_state = yyg->yy_start;
+
+	for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yyg->yy_last_accepting_state = yy_current_state;
+			yyg->yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 411 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+	register int yy_is_jam;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+	register char *yy_cp = yyg->yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yyg->yy_last_accepting_state = yy_current_state;
+		yyg->yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 411 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 410);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (yyscan_t yyscanner)
+#else
+    static int input  (yyscan_t yyscanner)
+#endif
+
+{
+	int c;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	*yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+	if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+			/* This was really a NUL. */
+			*yyg->yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+			++yyg->yy_c_buf_p;
+
+			switch ( yy_get_next_buffer( yyscanner ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart(yyin ,yyscanner);
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap(yyscanner ) )
+						return EOF;
+
+					if ( ! yyg->yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput(yyscanner);
+#else
+					return input(yyscanner);
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yyg->yy_c_buf_p;	/* cast for 8-bit char's */
+	*yyg->yy_c_buf_p = '\0';	/* preserve yytext */
+	yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+	if ( c == '\n' )
+		   
+    do{ yylineno++;
+        yycolumn=0;
+    }while(0)
+;
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack (yyscanner);
+		YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+	}
+
+	yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+	yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
+     */
+	yyensure_buffer_stack (yyscanner);
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*yyg->yy_c_buf_p = yyg->yy_hold_char;
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	yy_load_buffer_state(yyscanner );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer(b,file ,yyscanner);
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+	yyfree((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
+
+{
+	int oerrno = errno;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	yy_flush_buffer(b ,yyscanner);
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		yy_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  @param yyscanner The scanner object.
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	if (new_buffer == NULL)
+		return;
+
+	yyensure_buffer_stack(yyscanner);
+
+	/* This block is copied from yy_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*yyg->yy_c_buf_p = yyg->yy_hold_char;
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		yyg->yy_buffer_stack_top++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state(yyscanner );
+	yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  @param yyscanner The scanner object.
+ */
+void yypop_buffer_state (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	if (!YY_CURRENT_BUFFER)
+		return;
+
+	yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if (yyg->yy_buffer_stack_top > 0)
+		--yyg->yy_buffer_stack_top;
+
+	if (YY_CURRENT_BUFFER) {
+		yy_load_buffer_state(yyscanner );
+		yyg->yy_did_buffer_switch_on_eof = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (yyscan_t yyscanner)
+{
+	int num_to_alloc;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	if (!yyg->yy_buffer_stack) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								, yyscanner);
+		if ( ! yyg->yy_buffer_stack )
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+								  
+		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		yyg->yy_buffer_stack_max = num_to_alloc;
+		yyg->yy_buffer_stack_top = 0;
+		return;
+	}
+
+	if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+		yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
+								(yyg->yy_buffer_stack,
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								, yyscanner);
+		if ( ! yyg->yy_buffer_stack )
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+		/* zero only the new slots.*/
+		memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+		yyg->yy_buffer_stack_max = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer(b ,yyscanner );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+    
+	return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) yyalloc(n ,yyscanner );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer(buf,n ,yyscanner);
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+    static void yy_push_state (int  new_state , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yyg->yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yyg->yy_start_stack_depth * sizeof( int );
+
+		if ( ! yyg->yy_start_stack )
+			yyg->yy_start_stack = (int *) yyalloc(new_size ,yyscanner );
+
+		else
+			yyg->yy_start_stack = (int *) yyrealloc((void *) yyg->yy_start_stack,new_size ,yyscanner );
+
+		if ( ! yyg->yy_start_stack )
+			YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+		}
+
+	yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+}
+
+    static void yy_pop_state  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	if ( --yyg->yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]);
+}
+
+    static int yy_top_state  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1];
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		yytext[yyleng] = yyg->yy_hold_char; \
+		yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+		yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+		*yyg->yy_c_buf_p = '\0'; \
+		yyleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_lineno  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+    
+    return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_column  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+    
+    return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_in  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_lineno (int  line_number , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* lineno is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); 
+    
+    yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_column (int  column_no , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* column is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           yy_fatal_error( "yyset_column called with no buffer" , yyscanner); 
+    
+    yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  in_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyin = in_str ;
+}
+
+void yyset_out (FILE *  out_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyout = out_str ;
+}
+
+int yyget_debug  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yy_flex_debug;
+}
+
+void yyset_debug (int  bdebug , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * yyget_lval  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yylval;
+}
+
+void yyset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yylval = yylval_param;
+}
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+
+    *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+
+    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+    struct yyguts_t dummy_yyguts;
+
+    yyset_extra (yy_user_defined, &dummy_yyguts);
+
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+	
+    *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+	
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+    
+    /* By setting to 0xAA, we expose bugs in
+    yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+    
+    yyset_extra (yy_user_defined, *ptr_yy_globals);
+    
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    yyg->yy_buffer_stack = 0;
+    yyg->yy_buffer_stack_top = 0;
+    yyg->yy_buffer_stack_max = 0;
+    yyg->yy_c_buf_p = (char *) 0;
+    yyg->yy_init = 0;
+    yyg->yy_start = 0;
+
+    yyg->yy_start_stack_ptr = 0;
+    yyg->yy_start_stack_depth = 0;
+    yyg->yy_start_stack =  NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		yypop_buffer_state(yyscanner);
+	}
+
+	/* Destroy the stack itself. */
+	yyfree(yyg->yy_buffer_stack ,yyscanner);
+	yyg->yy_buffer_stack = NULL;
+
+    /* Destroy the start condition stack. */
+        yyfree(yyg->yy_start_stack ,yyscanner );
+        yyg->yy_start_stack = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * yylex() is called, initialization will occur. */
+    yy_init_globals( yyscanner);
+
+    /* Destroy the main struct (reentrant only). */
+    yyfree ( yyscanner , yyscanner );
+    yyscanner = NULL;
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size , yyscan_t yyscanner)
+{
+	return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr , yyscan_t yyscanner)
+{
+	free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+extern "C" {
+// Preprocessor interface.
+#include "compiler/preprocessor/preprocess.h"
+
+#define SETUP_CONTEXT(pp) \
+    TParseContext* context = (TParseContext*) pp->pC; \
+    struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
+
+// Preprocessor callbacks.
+void CPPDebugLogMsg(const char *msg)
+{
+    SETUP_CONTEXT(cpp);
+    context->infoSink.debug.message(EPrefixNone, msg);
+}
+
+void CPPWarningToInfoLog(const char *msg)
+{
+    SETUP_CONTEXT(cpp);
+    context->warning(yylineno, msg, "", "");
+}
+
+void CPPShInfoLogMsg(const char *msg)
+{
+    SETUP_CONTEXT(cpp);
+    context->error(yylineno, msg, "", "");
+    context->recover();
+}
+
+void CPPErrorToInfoLog(char *msg)
+{
+    SETUP_CONTEXT(cpp);
+    context->error(yylineno, msg, "", "");
+    context->recover();
+}
+
+void SetLineNumber(int line)
+{
+    SETUP_CONTEXT(cpp);
+    int string = 0;
+    DecodeSourceLoc(yylineno, &string, NULL);
+    yylineno = EncodeSourceLoc(string, line);
+}
+
+void SetStringNumber(int string)
+{
+    SETUP_CONTEXT(cpp);
+    int line = 0;
+    DecodeSourceLoc(yylineno, NULL, &line);
+    yylineno = EncodeSourceLoc(string, line);
+}
+
+int GetStringNumber()
+{
+    SETUP_CONTEXT(cpp);
+    int string = 0;
+    DecodeSourceLoc(yylineno, &string, NULL);
+    return string;
+}
+
+int GetLineNumber()
+{
+    SETUP_CONTEXT(cpp);
+    int line = 0;
+    DecodeSourceLoc(yylineno, NULL, &line);
+    return line;
+}
+
+void IncLineNumber()
+{
+    SETUP_CONTEXT(cpp);
+    int string = 0, line = 0;
+    DecodeSourceLoc(yylineno, &string, &line);
+    yylineno = EncodeSourceLoc(string, ++line);
+}
+
+void DecLineNumber()
+{
+    SETUP_CONTEXT(cpp);
+    int string = 0, line = 0;
+    DecodeSourceLoc(yylineno, &string, &line);
+    yylineno = EncodeSourceLoc(string, --line);
+}
+
+void HandlePragma(const char **tokens, int numTokens)
+{
+    SETUP_CONTEXT(cpp);
+    if (!strcmp(tokens[0], "optimize")) {
+        if (numTokens != 4) {
+            CPPShInfoLogMsg("optimize pragma syntax is incorrect");
+            return;
+        }
+        
+        if (strcmp(tokens[1], "(")) {
+            CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
+            return;
+        }
+            
+        if (!strcmp(tokens[2], "on"))
+            context->contextPragma.optimize = true;
+        else if (!strcmp(tokens[2], "off"))
+            context->contextPragma.optimize = false;
+        else {
+            CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
+            return;
+        }
+        
+        if (strcmp(tokens[3], ")")) {
+            CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
+            return;
+        }
+    } else if (!strcmp(tokens[0], "debug")) {
+        if (numTokens != 4) {
+            CPPShInfoLogMsg("debug pragma syntax is incorrect");
+            return;
+        }
+        
+        if (strcmp(tokens[1], "(")) {
+            CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
+            return;
+        }
+            
+        if (!strcmp(tokens[2], "on"))
+            context->contextPragma.debug = true;
+        else if (!strcmp(tokens[2], "off"))
+            context->contextPragma.debug = false;
+        else {
+            CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
+            return;
+        }
+        
+        if (strcmp(tokens[3], ")")) {
+            CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
+            return;
+        }
+    } else {
+#ifdef PRAGMA_TABLE
+        //
+        // implementation specific pragma
+        // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma
+        // For now, just ignore the pragma that the implementation cannot recognize
+        // An Example of one such implementation for a pragma that has a syntax like
+        // #pragma pragmaname(pragmavalue)
+        // This implementation stores the current pragmavalue against the pragma name in pragmaTable.
+        //        
+        if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {              
+            TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
+            TPragmaTable::iterator iter;
+            iter = pragmaTable.find(TString(tokens[0]));
+            if (iter != pragmaTable.end()) {
+                iter->second = tokens[2];
+            } else {
+                pragmaTable[ tokens[0] ] = tokens[2];
+            }        
+        } else if (numTokens >= 2) {
+            TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
+            TPragmaTable::iterator iter;
+            iter = pragmaTable.find(TString(tokens[0]));
+            if (iter != pragmaTable.end()) {
+                iter->second = tokens[1];
+            } else {
+                pragmaTable[ tokens[0] ] = tokens[1];
+            }
+        }
+#endif // PRAGMA_TABLE
+    }
+}
+
+void StoreStr(char *string)
+{
+    SETUP_CONTEXT(cpp);
+    TString strSrc;
+    strSrc = TString(string);
+
+    context->HashErrMsg = context->HashErrMsg + " " + strSrc;
+}
+
+const char* GetStrfromTStr(void)
+{
+    SETUP_CONTEXT(cpp);
+    cpp->ErrMsg = context->HashErrMsg.c_str();
+    return cpp->ErrMsg;
+}
+
+void ResetTString(void)
+{
+    SETUP_CONTEXT(cpp);
+    context->HashErrMsg = "";
+}
+
+TBehavior GetBehavior(const char* behavior)
+{
+    if (!strcmp("require", behavior))
+        return EBhRequire;
+    else if (!strcmp("enable", behavior))
+        return EBhEnable;
+    else if (!strcmp("disable", behavior))
+        return EBhDisable;
+    else if (!strcmp("warn", behavior))
+        return EBhWarn;
+    else {
+        CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
+        return EBhDisable;
+    }        
+}
+
+void updateExtensionBehavior(const char* extName, const char* behavior)
+{
+    SETUP_CONTEXT(cpp);
+    TBehavior behaviorVal = GetBehavior(behavior);
+    TMap<TString, TBehavior>:: iterator iter;
+    TString msg;
+    
+    // special cased for all extension
+    if (!strcmp(extName, "all")) {
+        if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
+            CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");  
+            return;
+        } else {
+            for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter)
+                iter->second = behaviorVal;
+        }        
+    } else {
+        iter = context->extensionBehavior.find(TString(extName));
+        if (iter == context->extensionBehavior.end()) {
+            switch (behaviorVal) {
+            case EBhRequire:
+                CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());  
+                break;
+            case EBhEnable:
+            case EBhWarn:
+            case EBhDisable:
+                msg = TString("extension '") + extName + "' is not supported";
+                context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); 
+                break;
+            }
+            return;
+        } else
+            iter->second = behaviorVal;
+    }
+}
+}  // extern "C"
+
+int string_input(char* buf, int max_size, yyscan_t yyscanner) {
+    int len;
+
+    if ((len = yylex_CPP(buf, max_size)) == 0)
+        return 0;
+    if (len >= max_size) 
+        YY_FATAL_ERROR("input buffer overflow, can't enlarge buffer because scanner uses REJECT");
+
+    buf[len] = ' ';
+    return len+1;
+}
+
+int check_type(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+    
+    int token = IDENTIFIER;
+    TSymbol* symbol = yyextra->symbolTable.find(yytext);
+    if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
+        TVariable* variable = static_cast<TVariable*>(symbol);
+        if (variable->isUserType()) {
+            yyextra->lexAfterType = true;
+            token = TYPE_NAME;
+        }
+    }
+    yylval->lex.symbol = symbol;
+    return token;
+}
+
+int reserved_word(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+    yyextra->error(yylineno, "Illegal use of reserved word", yytext, "");
+    yyextra->recover();
+    return 0;
+}
+
+void yyerror(TParseContext* context, const char* reason) {
+    struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
+
+    if (context->AfterEOF) {
+        context->error(yylineno, reason, "unexpected EOF", "");
+    } else {
+        context->error(yylineno, reason, yytext, "");
+    }
+    context->recover();
+}
+
+int glslang_initialize(TParseContext* context) {
+    yyscan_t scanner = NULL;
+    if (yylex_init_extra(context,&scanner))
+        return 1;
+
+    context->scanner = scanner;
+    return 0;
+}
+
+int glslang_finalize(TParseContext* context) {
+    yyscan_t scanner = context->scanner;
+    if (scanner == NULL) return 0;
+    
+    context->scanner = NULL;
+    return yylex_destroy(scanner);
+}
+
+void glslang_scan(int count, const char* const string[], const int length[],
+                  TParseContext* context) {
+    yyrestart(NULL,context->scanner);
+    yyset_lineno(EncodeSourceLoc(0, 1),context->scanner);
+    context->AfterEOF = false;
+    
+    // Init preprocessor.
+    cpp->pC = context;
+    cpp->PaWhichStr = 0;
+    cpp->PaArgv     = string;
+    cpp->PaArgc     = count;
+    cpp->PaStrLen   = length;
+    cpp->pastFirstStatement = 0;
+    ScanFromString(string[0]);
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp
new file mode 100644
index 0000000..d00c7a3
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp
@@ -0,0 +1,4710 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     INVARIANT = 258,
+     HIGH_PRECISION = 259,
+     MEDIUM_PRECISION = 260,
+     LOW_PRECISION = 261,
+     PRECISION = 262,
+     ATTRIBUTE = 263,
+     CONST_QUAL = 264,
+     BOOL_TYPE = 265,
+     FLOAT_TYPE = 266,
+     INT_TYPE = 267,
+     BREAK = 268,
+     CONTINUE = 269,
+     DO = 270,
+     ELSE = 271,
+     FOR = 272,
+     IF = 273,
+     DISCARD = 274,
+     RETURN = 275,
+     BVEC2 = 276,
+     BVEC3 = 277,
+     BVEC4 = 278,
+     IVEC2 = 279,
+     IVEC3 = 280,
+     IVEC4 = 281,
+     VEC2 = 282,
+     VEC3 = 283,
+     VEC4 = 284,
+     MATRIX2 = 285,
+     MATRIX3 = 286,
+     MATRIX4 = 287,
+     IN_QUAL = 288,
+     OUT_QUAL = 289,
+     INOUT_QUAL = 290,
+     UNIFORM = 291,
+     VARYING = 292,
+     STRUCT = 293,
+     VOID_TYPE = 294,
+     WHILE = 295,
+     SAMPLER2D = 296,
+     SAMPLERCUBE = 297,
+     IDENTIFIER = 298,
+     TYPE_NAME = 299,
+     FLOATCONSTANT = 300,
+     INTCONSTANT = 301,
+     BOOLCONSTANT = 302,
+     FIELD_SELECTION = 303,
+     LEFT_OP = 304,
+     RIGHT_OP = 305,
+     INC_OP = 306,
+     DEC_OP = 307,
+     LE_OP = 308,
+     GE_OP = 309,
+     EQ_OP = 310,
+     NE_OP = 311,
+     AND_OP = 312,
+     OR_OP = 313,
+     XOR_OP = 314,
+     MUL_ASSIGN = 315,
+     DIV_ASSIGN = 316,
+     ADD_ASSIGN = 317,
+     MOD_ASSIGN = 318,
+     LEFT_ASSIGN = 319,
+     RIGHT_ASSIGN = 320,
+     AND_ASSIGN = 321,
+     XOR_ASSIGN = 322,
+     OR_ASSIGN = 323,
+     SUB_ASSIGN = 324,
+     LEFT_PAREN = 325,
+     RIGHT_PAREN = 326,
+     LEFT_BRACKET = 327,
+     RIGHT_BRACKET = 328,
+     LEFT_BRACE = 329,
+     RIGHT_BRACE = 330,
+     DOT = 331,
+     COMMA = 332,
+     COLON = 333,
+     EQUAL = 334,
+     SEMICOLON = 335,
+     BANG = 336,
+     DASH = 337,
+     TILDE = 338,
+     PLUS = 339,
+     STAR = 340,
+     SLASH = 341,
+     PERCENT = 342,
+     LEFT_ANGLE = 343,
+     RIGHT_ANGLE = 344,
+     VERTICAL_BAR = 345,
+     CARET = 346,
+     AMPERSAND = 347,
+     QUESTION = 348
+   };
+#endif
+/* Tokens.  */
+#define INVARIANT 258
+#define HIGH_PRECISION 259
+#define MEDIUM_PRECISION 260
+#define LOW_PRECISION 261
+#define PRECISION 262
+#define ATTRIBUTE 263
+#define CONST_QUAL 264
+#define BOOL_TYPE 265
+#define FLOAT_TYPE 266
+#define INT_TYPE 267
+#define BREAK 268
+#define CONTINUE 269
+#define DO 270
+#define ELSE 271
+#define FOR 272
+#define IF 273
+#define DISCARD 274
+#define RETURN 275
+#define BVEC2 276
+#define BVEC3 277
+#define BVEC4 278
+#define IVEC2 279
+#define IVEC3 280
+#define IVEC4 281
+#define VEC2 282
+#define VEC3 283
+#define VEC4 284
+#define MATRIX2 285
+#define MATRIX3 286
+#define MATRIX4 287
+#define IN_QUAL 288
+#define OUT_QUAL 289
+#define INOUT_QUAL 290
+#define UNIFORM 291
+#define VARYING 292
+#define STRUCT 293
+#define VOID_TYPE 294
+#define WHILE 295
+#define SAMPLER2D 296
+#define SAMPLERCUBE 297
+#define IDENTIFIER 298
+#define TYPE_NAME 299
+#define FLOATCONSTANT 300
+#define INTCONSTANT 301
+#define BOOLCONSTANT 302
+#define FIELD_SELECTION 303
+#define LEFT_OP 304
+#define RIGHT_OP 305
+#define INC_OP 306
+#define DEC_OP 307
+#define LE_OP 308
+#define GE_OP 309
+#define EQ_OP 310
+#define NE_OP 311
+#define AND_OP 312
+#define OR_OP 313
+#define XOR_OP 314
+#define MUL_ASSIGN 315
+#define DIV_ASSIGN 316
+#define ADD_ASSIGN 317
+#define MOD_ASSIGN 318
+#define LEFT_ASSIGN 319
+#define RIGHT_ASSIGN 320
+#define AND_ASSIGN 321
+#define XOR_ASSIGN 322
+#define OR_ASSIGN 323
+#define SUB_ASSIGN 324
+#define LEFT_PAREN 325
+#define RIGHT_PAREN 326
+#define LEFT_BRACKET 327
+#define RIGHT_BRACKET 328
+#define LEFT_BRACE 329
+#define RIGHT_BRACE 330
+#define DOT 331
+#define COMMA 332
+#define COLON 333
+#define EQUAL 334
+#define SEMICOLON 335
+#define BANG 336
+#define DASH 337
+#define TILDE 338
+#define PLUS 339
+#define STAR 340
+#define SLASH 341
+#define PERCENT 342
+#define LEFT_ANGLE 343
+#define RIGHT_ANGLE 344
+#define VERTICAL_BAR 345
+#define CARET 346
+#define AMPERSAND 347
+#define QUESTION 348
+
+
+
+
+/* Copy the first part of user declarations.  */
+
+
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
+
+#include "compiler/SymbolTable.h"
+#include "compiler/ParseHelper.h"
+#include "GLSLANG/ShaderLang.h"
+
+#define YYLEX_PARAM context->scanner
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+
+{
+    struct {
+        TSourceLoc line;
+        union {
+            TString *string;
+            float f;
+            int i;
+            bool b;
+        };
+        TSymbol* symbol;
+    } lex;
+    struct {
+        TSourceLoc line;
+        TOperator op;
+        union {
+            TIntermNode* intermNode;
+            TIntermNodePair nodePair;
+            TIntermTyped* intermTypedNode;
+            TIntermAggregate* intermAggregate;
+        };
+        union {
+            TPublicType type;
+            TPrecision precision;
+            TQualifier qualifier;
+            TFunction* function;
+            TParameter param;
+            TTypeLine typeLine;
+            TTypeList* typeList;
+        };
+    } interm;
+}
+/* Line 187 of yacc.c.  */
+
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+extern int yylex(YYSTYPE* yylval_param, void* yyscanner);
+extern void yyerror(TParseContext* context, const char* reason);
+
+#define FRAG_VERT_ONLY(S, L) {  \
+    if (context->shaderType != SH_FRAGMENT_SHADER &&  \
+        context->shaderType != SH_VERTEX_SHADER) {  \
+        context->error(L, " supported in vertex/fragment shaders only ", S, "", "");  \
+        context->recover();  \
+    }  \
+}
+
+#define VERTEX_ONLY(S, L) {  \
+    if (context->shaderType != SH_VERTEX_SHADER) {  \
+        context->error(L, " supported in vertex shaders only ", S, "", "");  \
+        context->recover();  \
+    }  \
+}
+
+#define FRAG_ONLY(S, L) {  \
+    if (context->shaderType != SH_FRAGMENT_SHADER) {  \
+        context->error(L, " supported in fragment shaders only ", S, "", "");  \
+        context->recover();  \
+    }  \
+}
+
+
+/* Line 216 of yacc.c.  */
+
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+	     && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  69
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   1334
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  94
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  78
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  193
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  296
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   348
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
+      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+      85,    86,    87,    88,    89,    90,    91,    92,    93
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     5,     7,     9,    11,    13,    17,    19,
+      24,    26,    30,    33,    36,    38,    40,    42,    46,    49,
+      52,    55,    57,    60,    64,    67,    69,    71,    73,    75,
+      78,    81,    84,    86,    88,    90,    92,    96,   100,   102,
+     106,   110,   112,   114,   118,   122,   126,   130,   132,   136,
+     140,   142,   144,   146,   148,   152,   154,   158,   160,   164,
+     166,   172,   174,   178,   180,   182,   184,   186,   188,   190,
+     194,   196,   199,   202,   207,   210,   212,   214,   217,   221,
+     225,   228,   234,   238,   241,   245,   248,   249,   251,   253,
+     255,   257,   259,   263,   269,   276,   282,   284,   287,   292,
+     298,   303,   306,   308,   311,   313,   315,   317,   320,   322,
+     324,   327,   329,   331,   333,   335,   340,   342,   344,   346,
+     348,   350,   352,   354,   356,   358,   360,   362,   364,   366,
+     368,   370,   372,   374,   376,   378,   380,   386,   391,   393,
+     396,   400,   402,   406,   408,   413,   415,   417,   419,   421,
+     423,   425,   427,   429,   431,   434,   435,   436,   442,   444,
+     446,   449,   453,   455,   458,   460,   463,   469,   473,   475,
+     477,   482,   483,   490,   491,   500,   501,   509,   511,   513,
+     515,   516,   519,   523,   526,   529,   532,   536,   539,   541,
+     544,   546,   548,   549
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int16 yyrhs[] =
+{
+     168,     0,    -1,    43,    -1,    95,    -1,    46,    -1,    45,
+      -1,    47,    -1,    70,   122,    71,    -1,    96,    -1,    97,
+      72,    98,    73,    -1,    99,    -1,    97,    76,    48,    -1,
+      97,    51,    -1,    97,    52,    -1,   122,    -1,   100,    -1,
+     101,    -1,    97,    76,   101,    -1,   103,    71,    -1,   102,
+      71,    -1,   104,    39,    -1,   104,    -1,   104,   120,    -1,
+     103,    77,   120,    -1,   105,    70,    -1,   137,    -1,    43,
+      -1,    48,    -1,    97,    -1,    51,   106,    -1,    52,   106,
+      -1,   107,   106,    -1,    84,    -1,    82,    -1,    81,    -1,
+     106,    -1,   108,    85,   106,    -1,   108,    86,   106,    -1,
+     108,    -1,   109,    84,   108,    -1,   109,    82,   108,    -1,
+     109,    -1,   110,    -1,   111,    88,   110,    -1,   111,    89,
+     110,    -1,   111,    53,   110,    -1,   111,    54,   110,    -1,
+     111,    -1,   112,    55,   111,    -1,   112,    56,   111,    -1,
+     112,    -1,   113,    -1,   114,    -1,   115,    -1,   116,    57,
+     115,    -1,   116,    -1,   117,    59,   116,    -1,   117,    -1,
+     118,    58,   117,    -1,   118,    -1,   118,    93,   122,    78,
+     120,    -1,   119,    -1,   106,   121,   120,    -1,    79,    -1,
+      60,    -1,    61,    -1,    62,    -1,    69,    -1,   120,    -1,
+     122,    77,   120,    -1,   119,    -1,   125,    80,    -1,   133,
+      80,    -1,     7,   138,   139,    80,    -1,   126,    71,    -1,
+     128,    -1,   127,    -1,   128,   130,    -1,   127,    77,   130,
+      -1,   135,    43,    70,    -1,   137,    43,    -1,   137,    43,
+      72,   123,    73,    -1,   136,   131,   129,    -1,   131,   129,
+      -1,   136,   131,   132,    -1,   131,   132,    -1,    -1,    33,
+      -1,    34,    -1,    35,    -1,   137,    -1,   134,    -1,   133,
+      77,    43,    -1,   133,    77,    43,    72,    73,    -1,   133,
+      77,    43,    72,   123,    73,    -1,   133,    77,    43,    79,
+     146,    -1,   135,    -1,   135,    43,    -1,   135,    43,    72,
+      73,    -1,   135,    43,    72,   123,    73,    -1,   135,    43,
+      79,   146,    -1,     3,    43,    -1,   137,    -1,   136,   137,
+      -1,     9,    -1,     8,    -1,    37,    -1,     3,    37,    -1,
+      36,    -1,   139,    -1,   138,   139,    -1,     4,    -1,     5,
+      -1,     6,    -1,   140,    -1,   140,    72,   123,    73,    -1,
+      39,    -1,    11,    -1,    12,    -1,    10,    -1,    27,    -1,
+      28,    -1,    29,    -1,    21,    -1,    22,    -1,    23,    -1,
+      24,    -1,    25,    -1,    26,    -1,    30,    -1,    31,    -1,
+      32,    -1,    41,    -1,    42,    -1,   141,    -1,    44,    -1,
+      38,    43,    74,   142,    75,    -1,    38,    74,   142,    75,
+      -1,   143,    -1,   142,   143,    -1,   137,   144,    80,    -1,
+     145,    -1,   144,    77,   145,    -1,    43,    -1,    43,    72,
+     123,    73,    -1,   120,    -1,   124,    -1,   150,    -1,   149,
+      -1,   147,    -1,   156,    -1,   157,    -1,   160,    -1,   167,
+      -1,    74,    75,    -1,    -1,    -1,    74,   151,   155,   152,
+      75,    -1,   154,    -1,   149,    -1,    74,    75,    -1,    74,
+     155,    75,    -1,   148,    -1,   155,   148,    -1,    80,    -1,
+     122,    80,    -1,    18,    70,   122,    71,   158,    -1,   148,
+      16,   148,    -1,   148,    -1,   122,    -1,   135,    43,    79,
+     146,    -1,    -1,    40,    70,   161,   159,    71,   153,    -1,
+      -1,    15,   162,   148,    40,    70,   122,    71,    80,    -1,
+      -1,    17,    70,   163,   164,   166,    71,   153,    -1,   156,
+      -1,   147,    -1,   159,    -1,    -1,   165,    80,    -1,   165,
+      80,   122,    -1,    14,    80,    -1,    13,    80,    -1,    20,
+      80,    -1,    20,   122,    80,    -1,    19,    80,    -1,   169,
+      -1,   168,   169,    -1,   170,    -1,   124,    -1,    -1,   125,
+     171,   154,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   153,   153,   188,   191,   204,   209,   214,   220,   223,
+     296,   299,   408,   418,   431,   439,   538,   541,   549,   553,
+     560,   564,   571,   577,   586,   594,   656,   663,   673,   676,
+     686,   696,   717,   718,   719,   724,   725,   734,   746,   747,
+     755,   766,   770,   771,   781,   791,   801,   814,   815,   825,
+     838,   842,   846,   850,   851,   864,   865,   878,   879,   892,
+     893,   910,   911,   924,   925,   926,   927,   928,   932,   935,
+     946,   954,   979,   984,   991,  1027,  1030,  1037,  1045,  1066,
+    1085,  1096,  1125,  1130,  1140,  1145,  1155,  1158,  1161,  1164,
+    1170,  1177,  1187,  1199,  1217,  1241,  1264,  1268,  1282,  1302,
+    1331,  1351,  1427,  1436,  1459,  1462,  1468,  1476,  1484,  1492,
+    1495,  1502,  1505,  1508,  1514,  1517,  1532,  1536,  1540,  1544,
+    1553,  1558,  1563,  1568,  1573,  1578,  1583,  1588,  1593,  1598,
+    1604,  1610,  1616,  1621,  1626,  1631,  1644,  1657,  1665,  1668,
+    1683,  1714,  1718,  1724,  1732,  1748,  1752,  1756,  1757,  1763,
+    1764,  1765,  1766,  1767,  1771,  1772,  1772,  1772,  1780,  1781,
+    1786,  1789,  1797,  1800,  1806,  1807,  1811,  1819,  1823,  1833,
+    1838,  1855,  1855,  1860,  1860,  1867,  1867,  1875,  1878,  1884,
+    1887,  1893,  1897,  1904,  1911,  1918,  1925,  1936,  1945,  1949,
+    1956,  1959,  1965,  1965
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "INVARIANT", "HIGH_PRECISION",
+  "MEDIUM_PRECISION", "LOW_PRECISION", "PRECISION", "ATTRIBUTE",
+  "CONST_QUAL", "BOOL_TYPE", "FLOAT_TYPE", "INT_TYPE", "BREAK", "CONTINUE",
+  "DO", "ELSE", "FOR", "IF", "DISCARD", "RETURN", "BVEC2", "BVEC3",
+  "BVEC4", "IVEC2", "IVEC3", "IVEC4", "VEC2", "VEC3", "VEC4", "MATRIX2",
+  "MATRIX3", "MATRIX4", "IN_QUAL", "OUT_QUAL", "INOUT_QUAL", "UNIFORM",
+  "VARYING", "STRUCT", "VOID_TYPE", "WHILE", "SAMPLER2D", "SAMPLERCUBE",
+  "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT", "INTCONSTANT",
+  "BOOLCONSTANT", "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP",
+  "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP",
+  "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN",
+  "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN",
+  "SUB_ASSIGN", "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACKET",
+  "RIGHT_BRACKET", "LEFT_BRACE", "RIGHT_BRACE", "DOT", "COMMA", "COLON",
+  "EQUAL", "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", "STAR", "SLASH",
+  "PERCENT", "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", "CARET",
+  "AMPERSAND", "QUESTION", "$accept", "variable_identifier",
+  "primary_expression", "postfix_expression", "integer_expression",
+  "function_call", "function_call_or_method", "function_call_generic",
+  "function_call_header_no_parameters",
+  "function_call_header_with_parameters", "function_call_header",
+  "function_identifier", "unary_expression", "unary_operator",
+  "multiplicative_expression", "additive_expression", "shift_expression",
+  "relational_expression", "equality_expression", "and_expression",
+  "exclusive_or_expression", "inclusive_or_expression",
+  "logical_and_expression", "logical_xor_expression",
+  "logical_or_expression", "conditional_expression",
+  "assignment_expression", "assignment_operator", "expression",
+  "constant_expression", "declaration", "function_prototype",
+  "function_declarator", "function_header_with_parameters",
+  "function_header", "parameter_declarator", "parameter_declaration",
+  "parameter_qualifier", "parameter_type_specifier",
+  "init_declarator_list", "single_declaration", "fully_specified_type",
+  "type_qualifier", "type_specifier", "precision_qualifier",
+  "type_specifier_no_prec", "type_specifier_nonarray", "struct_specifier",
+  "struct_declaration_list", "struct_declaration",
+  "struct_declarator_list", "struct_declarator", "initializer",
+  "declaration_statement", "statement", "simple_statement",
+  "compound_statement", "@1", "@2", "statement_no_new_scope",
+  "compound_statement_no_new_scope", "statement_list",
+  "expression_statement", "selection_statement",
+  "selection_rest_statement", "condition", "iteration_statement", "@3",
+  "@4", "@5", "for_init_statement", "conditionopt", "for_rest_statement",
+  "jump_statement", "translation_unit", "external_declaration",
+  "function_definition", "@6", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
+     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
+     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
+     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
+     345,   346,   347,   348
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    94,    95,    96,    96,    96,    96,    96,    97,    97,
+      97,    97,    97,    97,    98,    99,   100,   100,   101,   101,
+     102,   102,   103,   103,   104,   105,   105,   105,   106,   106,
+     106,   106,   107,   107,   107,   108,   108,   108,   109,   109,
+     109,   110,   111,   111,   111,   111,   111,   112,   112,   112,
+     113,   114,   115,   116,   116,   117,   117,   118,   118,   119,
+     119,   120,   120,   121,   121,   121,   121,   121,   122,   122,
+     123,   124,   124,   124,   125,   126,   126,   127,   127,   128,
+     129,   129,   130,   130,   130,   130,   131,   131,   131,   131,
+     132,   133,   133,   133,   133,   133,   134,   134,   134,   134,
+     134,   134,   135,   135,   136,   136,   136,   136,   136,   137,
+     137,   138,   138,   138,   139,   139,   140,   140,   140,   140,
+     140,   140,   140,   140,   140,   140,   140,   140,   140,   140,
+     140,   140,   140,   140,   140,   140,   141,   141,   142,   142,
+     143,   144,   144,   145,   145,   146,   147,   148,   148,   149,
+     149,   149,   149,   149,   150,   151,   152,   150,   153,   153,
+     154,   154,   155,   155,   156,   156,   157,   158,   158,   159,
+     159,   161,   160,   162,   160,   163,   160,   164,   164,   165,
+     165,   166,   166,   167,   167,   167,   167,   167,   168,   168,
+     169,   169,   171,   170
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     1,     1,     1,     1,     1,     3,     1,     4,
+       1,     3,     2,     2,     1,     1,     1,     3,     2,     2,
+       2,     1,     2,     3,     2,     1,     1,     1,     1,     2,
+       2,     2,     1,     1,     1,     1,     3,     3,     1,     3,
+       3,     1,     1,     3,     3,     3,     3,     1,     3,     3,
+       1,     1,     1,     1,     3,     1,     3,     1,     3,     1,
+       5,     1,     3,     1,     1,     1,     1,     1,     1,     3,
+       1,     2,     2,     4,     2,     1,     1,     2,     3,     3,
+       2,     5,     3,     2,     3,     2,     0,     1,     1,     1,
+       1,     1,     3,     5,     6,     5,     1,     2,     4,     5,
+       4,     2,     1,     2,     1,     1,     1,     2,     1,     1,
+       2,     1,     1,     1,     1,     4,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     5,     4,     1,     2,
+       3,     1,     3,     1,     4,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     2,     0,     0,     5,     1,     1,
+       2,     3,     1,     2,     1,     2,     5,     3,     1,     1,
+       4,     0,     6,     0,     8,     0,     7,     1,     1,     1,
+       0,     2,     3,     2,     2,     2,     3,     2,     1,     2,
+       1,     1,     0,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       0,     0,   111,   112,   113,     0,   105,   104,   119,   117,
+     118,   123,   124,   125,   126,   127,   128,   120,   121,   122,
+     129,   130,   131,   108,   106,     0,   116,   132,   133,   135,
+     191,   192,     0,    76,    86,     0,    91,    96,     0,   102,
+       0,   109,   114,   134,     0,   188,   190,   107,   101,     0,
+       0,     0,    71,     0,    74,    86,     0,    87,    88,    89,
+      77,     0,    86,     0,    72,    97,   103,   110,     0,     1,
+     189,     0,     0,     0,     0,   138,     0,   193,    78,    83,
+      85,    90,     0,    92,    79,     0,     0,     2,     5,     4,
+       6,    27,     0,     0,     0,    34,    33,    32,     3,     8,
+      28,    10,    15,    16,     0,     0,    21,     0,    35,     0,
+      38,    41,    42,    47,    50,    51,    52,    53,    55,    57,
+      59,    70,     0,    25,    73,     0,   143,     0,   141,   137,
+     139,     0,     0,   173,     0,     0,     0,     0,     0,   155,
+     160,   164,    35,    61,    68,     0,   146,     0,   102,   149,
+     162,   148,   147,     0,   150,   151,   152,   153,    80,    82,
+      84,     0,     0,    98,     0,   145,   100,    29,    30,     0,
+      12,    13,     0,     0,    19,    18,     0,   116,    22,    24,
+      31,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   115,   136,     0,     0,   140,
+     184,   183,     0,   175,     0,   187,   185,     0,   171,   154,
+       0,    64,    65,    66,    67,    63,     0,     0,   165,   161,
+     163,     0,    93,     0,    95,    99,     7,     0,    14,    26,
+      11,    17,    23,    36,    37,    40,    39,    45,    46,    43,
+      44,    48,    49,    54,    56,    58,     0,     0,   142,     0,
+       0,     0,   186,     0,   156,    62,    69,     0,    94,     9,
+       0,   144,     0,   178,   177,   180,     0,   169,     0,     0,
+       0,    81,    60,     0,   179,     0,     0,   168,   166,     0,
+       0,   157,     0,   181,     0,     0,     0,   159,   172,   158,
+       0,   182,   176,   167,   170,   174
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,    98,    99,   100,   227,   101,   102,   103,   104,   105,
+     106,   107,   142,   109,   110,   111,   112,   113,   114,   115,
+     116,   117,   118,   119,   120,   143,   144,   216,   145,   122,
+     146,   147,    32,    33,    34,    79,    60,    61,    80,    35,
+      36,    37,    38,   123,    40,    41,    42,    43,    74,    75,
+     127,   128,   166,   149,   150,   151,   152,   210,   270,   288,
+     289,   153,   154,   155,   278,   269,   156,   253,   202,   250,
+     265,   275,   276,   157,    44,    45,    46,    53
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -250
+static const yytype_int16 yypact[] =
+{
+    1225,    36,  -250,  -250,  -250,   150,  -250,  -250,  -250,  -250,
+    -250,  -250,  -250,  -250,  -250,  -250,  -250,  -250,  -250,  -250,
+    -250,  -250,  -250,  -250,  -250,   -33,  -250,  -250,  -250,  -250,
+    -250,   -60,   -22,   -17,    21,   -62,  -250,    22,  1266,  -250,
+    1290,  -250,    11,  -250,  1138,  -250,  -250,  -250,  -250,  1290,
+      14,  1266,  -250,    27,  -250,    34,    41,  -250,  -250,  -250,
+    -250,  1266,   129,    61,  -250,    17,  -250,  -250,   908,  -250,
+    -250,    31,  1266,    72,  1042,  -250,   283,  -250,  -250,  -250,
+    -250,    90,  1266,   -46,  -250,   194,   908,    65,  -250,  -250,
+    -250,  -250,   908,   908,   908,  -250,  -250,  -250,  -250,  -250,
+     -40,  -250,  -250,  -250,    80,   -25,   975,    87,  -250,   908,
+      35,    13,  -250,   -26,    68,  -250,  -250,  -250,   110,   109,
+     -54,  -250,    96,  -250,  -250,  1083,    98,    33,  -250,  -250,
+    -250,    91,    92,  -250,   104,   107,    99,   760,   108,   105,
+    -250,  -250,    24,  -250,  -250,    37,  -250,   -60,   112,  -250,
+    -250,  -250,  -250,   365,  -250,  -250,  -250,  -250,   111,  -250,
+    -250,   827,   908,  -250,   113,  -250,  -250,  -250,  -250,     4,
+    -250,  -250,   908,  1179,  -250,  -250,   908,   114,  -250,  -250,
+    -250,   908,   908,   908,   908,   908,   908,   908,   908,   908,
+     908,   908,   908,   908,   908,  -250,  -250,   908,    72,  -250,
+    -250,  -250,   447,  -250,   908,  -250,  -250,    42,  -250,  -250,
+     447,  -250,  -250,  -250,  -250,  -250,   908,   908,  -250,  -250,
+    -250,   908,  -250,   115,  -250,  -250,  -250,   116,   117,  -250,
+     120,  -250,  -250,  -250,  -250,    35,    35,  -250,  -250,  -250,
+    -250,   -26,   -26,  -250,   110,   109,    51,   119,  -250,   144,
+     611,    23,  -250,   693,   447,  -250,  -250,   122,  -250,  -250,
+     908,  -250,   123,  -250,  -250,   693,   447,   117,   153,   126,
+     128,  -250,  -250,   908,  -250,   127,   137,   171,  -250,   130,
+     529,  -250,    28,   908,   529,   447,   908,  -250,  -250,  -250,
+     131,   117,  -250,  -250,  -250,  -250
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -250,  -250,  -250,  -250,  -250,  -250,  -250,    39,  -250,  -250,
+    -250,  -250,   -45,  -250,   -18,  -250,   -79,   -30,  -250,  -250,
+    -250,    38,    52,    20,  -250,   -63,   -85,  -250,   -92,   -71,
+       6,     9,  -250,  -250,  -250,   132,   172,   166,   148,  -250,
+    -250,  -246,   -21,     0,   226,   -24,  -250,  -250,   162,   -66,
+    -250,    45,  -159,    -3,  -136,  -249,  -250,  -250,  -250,   -36,
+     196,    46,     1,  -250,  -250,   -13,  -250,  -250,  -250,  -250,
+    -250,  -250,  -250,  -250,  -250,   211,  -250,  -250
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -76
+static const yytype_int16 yytable[] =
+{
+      39,   165,   169,   224,   193,   121,    30,   268,   130,    31,
+      50,   170,   171,    62,   164,    63,    67,   220,    64,   268,
+      52,   178,   121,   108,    56,    71,   161,   185,   186,     6,
+       7,   287,   172,   162,    62,   287,   173,    56,    66,   194,
+     108,    51,     6,     7,    39,   207,   175,   167,   168,    54,
+      30,    73,   176,    31,    57,    58,    59,    23,    24,   130,
+      55,    81,   187,   188,   180,    65,   249,    57,    58,    59,
+      23,    24,    73,    47,    73,   226,   148,   165,    47,    48,
+     228,   217,    81,    68,   211,   212,   213,    84,    72,    85,
+     223,   232,   -75,   214,   266,   183,    86,   184,   121,   290,
+     217,    76,   246,   215,    83,   217,   237,   238,   239,   240,
+     198,   124,   251,   199,   217,   126,   108,   218,   220,   217,
+     181,   182,   252,   189,   190,    73,   247,   294,   217,   260,
+     277,   255,   256,   158,   121,   -26,   233,   234,   108,   108,
+     108,   108,   108,   108,   108,   108,   108,   108,   108,   293,
+     257,   174,   108,   148,     2,     3,     4,   179,   121,   241,
+     242,   267,    57,    58,    59,   235,   236,   191,   192,   195,
+     197,   200,   201,   267,   203,   272,   108,   204,   208,   205,
+     209,   282,   -25,   221,   262,   -20,   225,   285,   258,   259,
+     -27,   291,   261,   273,   217,   271,   279,   280,     2,     3,
+       4,   165,   148,   281,     8,     9,    10,   283,   284,   286,
+     148,   295,   231,   245,   159,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    78,    82,   243,
+     160,    49,    25,    26,   125,    27,    28,    87,    29,    88,
+      89,    90,    91,   248,   244,    92,    93,   263,   292,    77,
+     148,   264,   274,   148,   148,    70,   254,     0,     0,     0,
+       0,     0,     0,     0,    94,   148,   148,   163,     0,     0,
+       0,     0,     0,     0,     0,    95,    96,     0,    97,     0,
+     148,     0,     0,     0,   148,   148,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,   131,   132,   133,     0,
+     134,   135,   136,   137,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,     0,     0,     0,    23,
+      24,    25,    26,   138,    27,    28,    87,    29,    88,    89,
+      90,    91,     0,     0,    92,    93,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    94,     0,     0,     0,   139,   140,     0,
+       0,     0,     0,   141,    95,    96,     0,    97,     1,     2,
+       3,     4,     5,     6,     7,     8,     9,    10,   131,   132,
+     133,     0,   134,   135,   136,   137,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,     0,     0,
+       0,    23,    24,    25,    26,   138,    27,    28,    87,    29,
+      88,    89,    90,    91,     0,     0,    92,    93,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    94,     0,     0,     0,   139,
+     219,     0,     0,     0,     0,   141,    95,    96,     0,    97,
+       1,     2,     3,     4,     5,     6,     7,     8,     9,    10,
+     131,   132,   133,     0,   134,   135,   136,   137,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+       0,     0,     0,    23,    24,    25,    26,   138,    27,    28,
+      87,    29,    88,    89,    90,    91,     0,     0,    92,    93,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    94,     0,     0,
+       0,   139,     0,     0,     0,     0,     0,   141,    95,    96,
+       0,    97,     1,     2,     3,     4,     5,     6,     7,     8,
+       9,    10,   131,   132,   133,     0,   134,   135,   136,   137,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,     0,     0,     0,    23,    24,    25,    26,   138,
+      27,    28,    87,    29,    88,    89,    90,    91,     0,     0,
+      92,    93,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    94,
+       0,     0,     0,    76,     0,     0,     0,     0,     0,   141,
+      95,    96,     0,    97,     1,     2,     3,     4,     5,     6,
+       7,     8,     9,    10,     0,     0,     0,     0,     0,     0,
+       0,     0,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,     0,     0,     0,    23,    24,    25,
+      26,     0,    27,    28,    87,    29,    88,    89,    90,    91,
+       0,     0,    92,    93,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    94,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   141,    95,    96,     0,    97,    56,     2,     3,     4,
+       0,     6,     7,     8,     9,    10,     0,     0,     0,     0,
+       0,     0,     0,     0,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,     0,     0,     0,    23,
+      24,    25,    26,     0,    27,    28,    87,    29,    88,    89,
+      90,    91,     0,     0,    92,    93,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    94,     2,     3,     4,     0,     0,     0,
+       8,     9,    10,     0,    95,    96,     0,    97,     0,     0,
+       0,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,     0,     0,     0,     0,     0,    25,    26,
+       0,    27,    28,    87,    29,    88,    89,    90,    91,     0,
+       0,    92,    93,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      94,     2,     3,     4,     0,     0,     0,     8,     9,    10,
+     206,    95,    96,     0,    97,     0,     0,     0,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+       0,     0,     0,     0,     0,    25,    26,     0,    27,    28,
+      87,    29,    88,    89,    90,    91,     0,     0,    92,    93,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    94,     0,     0,
+     222,     0,     0,     0,     0,     0,     0,     0,    95,    96,
+       0,    97,     2,     3,     4,     0,     0,     0,     8,     9,
+      10,     0,     0,     0,     0,     0,     0,     0,     0,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,     0,     0,     0,     0,     0,    25,    26,     0,    27,
+      28,    87,    29,    88,    89,    90,    91,     0,     0,    92,
+      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    94,     2,
+       3,     4,     0,     0,     0,     8,     9,    10,     0,    95,
+      96,     0,    97,     0,     0,     0,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,     0,     0,
+       0,     0,     0,    25,   177,     0,    27,    28,    87,    29,
+      88,    89,    90,    91,     0,     0,    92,    93,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    94,     2,     3,     4,     0,
+       0,     0,     8,     9,    10,     0,    95,    96,     0,    97,
+       0,     0,     0,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,     0,     0,     0,     0,     0,
+      25,    26,     0,    27,    28,     0,    29,     2,     3,     4,
+       0,     0,     0,     8,     9,    10,     0,     0,     0,     0,
+       0,     0,     0,     0,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,     0,   129,     0,     0,
+       0,    25,    26,     0,    27,    28,     0,    29,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    69,     0,
+       0,     1,     2,     3,     4,     5,     6,     7,     8,     9,
+      10,     0,     0,     0,     0,     0,     0,     0,   196,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,     0,     0,     0,    23,    24,    25,    26,     0,    27,
+      28,     0,    29,     2,     3,     4,     0,     0,     0,     8,
+       9,    10,     0,     0,     0,     0,     0,     0,     0,     0,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,     0,     0,     0,     0,     0,    25,    26,     0,
+      27,    28,   229,    29,     0,     0,     0,   230,     1,     2,
+       3,     4,     5,     6,     7,     8,     9,    10,     0,     0,
+       0,     0,     0,     0,     0,     0,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,     0,     0,
+       0,    23,    24,    25,    26,     0,    27,    28,     0,    29,
+       2,     3,     4,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,     0,     0,     0,     0,     0,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       8,     9,    10,     0,    25,    26,     0,    27,    28,     0,
+      29,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,     0,     0,     0,     0,     0,    25,    26,
+       0,    27,    28,     0,    29
+};
+
+static const yytype_int16 yycheck[] =
+{
+       0,    86,    94,   162,    58,    68,     0,   253,    74,     0,
+      43,    51,    52,    34,    85,    77,    40,   153,    80,   265,
+      80,   106,    85,    68,     3,    49,    72,    53,    54,     8,
+       9,   280,    72,    79,    55,   284,    76,     3,    38,    93,
+      85,    74,     8,     9,    44,   137,    71,    92,    93,    71,
+      44,    51,    77,    44,    33,    34,    35,    36,    37,   125,
+      77,    61,    88,    89,   109,    43,   202,    33,    34,    35,
+      36,    37,    72,    37,    74,    71,    76,   162,    37,    43,
+     172,    77,    82,    72,    60,    61,    62,    70,    74,    72,
+     161,   176,    71,    69,    71,    82,    79,    84,   161,    71,
+      77,    74,   194,    79,    43,    77,   185,   186,   187,   188,
+      77,    80,   204,    80,    77,    43,   161,    80,   254,    77,
+      85,    86,    80,    55,    56,   125,   197,   286,    77,    78,
+     266,   216,   217,    43,   197,    70,   181,   182,   183,   184,
+     185,   186,   187,   188,   189,   190,   191,   192,   193,   285,
+     221,    71,   197,   153,     4,     5,     6,    70,   221,   189,
+     190,   253,    33,    34,    35,   183,   184,    57,    59,    73,
+      72,    80,    80,   265,    70,   260,   221,    70,    70,    80,
+      75,   273,    70,    72,    40,    71,    73,    16,    73,    73,
+      70,   283,    73,    70,    77,    73,    43,    71,     4,     5,
+       6,   286,   202,    75,    10,    11,    12,    80,    71,    79,
+     210,    80,   173,   193,    82,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    30,    31,    32,    55,    62,   191,
+      82,     5,    38,    39,    72,    41,    42,    43,    44,    45,
+      46,    47,    48,   198,   192,    51,    52,   250,   284,    53,
+     250,   250,   265,   253,   254,    44,   210,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    70,   265,   266,    73,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    81,    82,    -1,    84,    -1,
+     280,    -1,    -1,    -1,   284,   285,     3,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    -1,
+      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    36,
+      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+      47,    48,    -1,    -1,    51,    52,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    70,    -1,    -1,    -1,    74,    75,    -1,
+      -1,    -1,    -1,    80,    81,    82,    -1,    84,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    -1,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
+      -1,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    -1,    -1,    51,    52,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    70,    -1,    -1,    -1,    74,
+      75,    -1,    -1,    -1,    -1,    80,    81,    82,    -1,    84,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    -1,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      -1,    -1,    -1,    36,    37,    38,    39,    40,    41,    42,
+      43,    44,    45,    46,    47,    48,    -1,    -1,    51,    52,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    70,    -1,    -1,
+      -1,    74,    -1,    -1,    -1,    -1,    -1,    80,    81,    82,
+      -1,    84,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    -1,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    -1,    -1,    -1,    36,    37,    38,    39,    40,
+      41,    42,    43,    44,    45,    46,    47,    48,    -1,    -1,
+      51,    52,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    70,
+      -1,    -1,    -1,    74,    -1,    -1,    -1,    -1,    -1,    80,
+      81,    82,    -1,    84,     3,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    -1,    -1,    -1,    36,    37,    38,
+      39,    -1,    41,    42,    43,    44,    45,    46,    47,    48,
+      -1,    -1,    51,    52,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    70,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    80,    81,    82,    -1,    84,     3,     4,     5,     6,
+      -1,     8,     9,    10,    11,    12,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    36,
+      37,    38,    39,    -1,    41,    42,    43,    44,    45,    46,
+      47,    48,    -1,    -1,    51,    52,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    70,     4,     5,     6,    -1,    -1,    -1,
+      10,    11,    12,    -1,    81,    82,    -1,    84,    -1,    -1,
+      -1,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,
+      -1,    41,    42,    43,    44,    45,    46,    47,    48,    -1,
+      -1,    51,    52,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      70,     4,     5,     6,    -1,    -1,    -1,    10,    11,    12,
+      80,    81,    82,    -1,    84,    -1,    -1,    -1,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      -1,    -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,
+      43,    44,    45,    46,    47,    48,    -1,    -1,    51,    52,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    70,    -1,    -1,
+      73,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    81,    82,
+      -1,    84,     4,     5,     6,    -1,    -1,    -1,    10,    11,
+      12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    -1,    -1,    -1,    -1,    -1,    38,    39,    -1,    41,
+      42,    43,    44,    45,    46,    47,    48,    -1,    -1,    51,
+      52,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    70,     4,
+       5,     6,    -1,    -1,    -1,    10,    11,    12,    -1,    81,
+      82,    -1,    84,    -1,    -1,    -1,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
+      -1,    -1,    -1,    38,    39,    -1,    41,    42,    43,    44,
+      45,    46,    47,    48,    -1,    -1,    51,    52,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    70,     4,     5,     6,    -1,
+      -1,    -1,    10,    11,    12,    -1,    81,    82,    -1,    84,
+      -1,    -1,    -1,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
+      38,    39,    -1,    41,    42,    -1,    44,     4,     5,     6,
+      -1,    -1,    -1,    10,    11,    12,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    -1,    75,    -1,    -1,
+      -1,    38,    39,    -1,    41,    42,    -1,    44,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     0,    -1,
+      -1,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    75,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    -1,    -1,    -1,    36,    37,    38,    39,    -1,    41,
+      42,    -1,    44,     4,     5,     6,    -1,    -1,    -1,    10,
+      11,    12,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,    -1,
+      41,    42,    43,    44,    -1,    -1,    -1,    48,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
+      -1,    36,    37,    38,    39,    -1,    41,    42,    -1,    44,
+       4,     5,     6,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      10,    11,    12,    -1,    38,    39,    -1,    41,    42,    -1,
+      44,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    -1,    -1,    -1,    -1,    -1,    38,    39,
+      -1,    41,    42,    -1,    44
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    36,    37,    38,    39,    41,    42,    44,
+     124,   125,   126,   127,   128,   133,   134,   135,   136,   137,
+     138,   139,   140,   141,   168,   169,   170,    37,    43,   138,
+      43,    74,    80,   171,    71,    77,     3,    33,    34,    35,
+     130,   131,   136,    77,    80,    43,   137,   139,    72,     0,
+     169,   139,    74,   137,   142,   143,    74,   154,   130,   129,
+     132,   137,   131,    43,    70,    72,    79,    43,    45,    46,
+      47,    48,    51,    52,    70,    81,    82,    84,    95,    96,
+      97,    99,   100,   101,   102,   103,   104,   105,   106,   107,
+     108,   109,   110,   111,   112,   113,   114,   115,   116,   117,
+     118,   119,   123,   137,    80,   142,    43,   144,   145,    75,
+     143,    13,    14,    15,    17,    18,    19,    20,    40,    74,
+      75,    80,   106,   119,   120,   122,   124,   125,   137,   147,
+     148,   149,   150,   155,   156,   157,   160,   167,    43,   129,
+     132,    72,    79,    73,   123,   120,   146,   106,   106,   122,
+      51,    52,    72,    76,    71,    71,    77,    39,   120,    70,
+     106,    85,    86,    82,    84,    53,    54,    88,    89,    55,
+      56,    57,    59,    58,    93,    73,    75,    72,    77,    80,
+      80,    80,   162,    70,    70,    80,    80,   122,    70,    75,
+     151,    60,    61,    62,    69,    79,   121,    77,    80,    75,
+     148,    72,    73,   123,   146,    73,    71,    98,   122,    43,
+      48,   101,   120,   106,   106,   108,   108,   110,   110,   110,
+     110,   111,   111,   115,   116,   117,   122,   123,   145,   148,
+     163,   122,    80,   161,   155,   120,   120,   123,    73,    73,
+      78,    73,    40,   147,   156,   164,    71,   122,   135,   159,
+     152,    73,   120,    70,   159,   165,   166,   148,   158,    43,
+      71,    75,   122,    80,    71,    16,    79,   149,   153,   154,
+      71,   122,   153,   148,   146,    80
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (context, YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (YYID (0))
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value, context); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, TParseContext* context)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, context)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    TParseContext* context;
+#endif
+{
+  if (!yyvaluep)
+    return;
+  YYUSE (context);
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, TParseContext* context)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, context)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    TParseContext* context;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, context);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule, TParseContext* context)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule, context)
+    YYSTYPE *yyvsp;
+    int yyrule;
+    TParseContext* context;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       		       , context);
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule, context); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, TParseContext* context)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, context)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    TParseContext* context;
+#endif
+{
+  YYUSE (yyvaluep);
+  YYUSE (context);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+	break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (TParseContext* context);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (TParseContext* context)
+#else
+int
+yyparse (context)
+    TParseContext* context;
+#endif
+#endif
+{
+  /* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+
+    {
+        // The symbol table search was done in the lexical phase
+        const TSymbol* symbol = (yyvsp[(1) - (1)].lex).symbol;
+        const TVariable* variable;
+        if (symbol == 0) {
+            context->error((yyvsp[(1) - (1)].lex).line, "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str(), "");
+            context->recover();
+            TType type(EbtFloat, EbpUndefined);
+            TVariable* fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type);
+            context->symbolTable.insert(*fakeVariable);
+            variable = fakeVariable;
+        } else {
+            // This identifier can only be a variable type symbol
+            if (! symbol->isVariable()) {
+                context->error((yyvsp[(1) - (1)].lex).line, "variable expected", (yyvsp[(1) - (1)].lex).string->c_str(), "");
+                context->recover();
+            }
+            variable = static_cast<const TVariable*>(symbol);
+        }
+
+        // don't delete $1.string, it's used by error recovery, and the pool
+        // pop will reclaim the memory
+
+        if (variable->getType().getQualifier() == EvqConst ) {
+            ConstantUnion* constArray = variable->getConstPointer();
+            TType t(variable->getType());
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(constArray, t, (yyvsp[(1) - (1)].lex).line);
+        } else
+            (yyval.interm.intermTypedNode) = context->intermediate.addSymbol(variable->getUniqueId(),
+                                                     variable->getName(),
+                                                     variable->getType(), (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 3:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 4:
+
+    {
+        //
+        // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
+        // check for overflow for constants
+        //
+        if (abs((yyvsp[(1) - (1)].lex).i) >= (1 << 16)) {
+            context->error((yyvsp[(1) - (1)].lex).line, " integer constant overflow", "", "");
+            context->recover();
+        }
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray->setIConst((yyvsp[(1) - (1)].lex).i);
+        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 5:
+
+    {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray->setFConst((yyvsp[(1) - (1)].lex).f);
+        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 6:
+
+    {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray->setBConst((yyvsp[(1) - (1)].lex).b);
+        (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 7:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(2) - (3)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 8:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 9:
+
+    {
+        if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) {
+            if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode())
+                context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str(), "");
+            else
+                context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
+            context->recover();
+        }
+        if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst && (yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
+            if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { // constant folding for arrays
+                (yyval.interm.intermTypedNode) = context->addConstArrayNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+            } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) {  // constant folding for vectors
+                TVectorFields fields;
+                fields.num = 1;
+                fields.offsets[0] = (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); // need to do it this way because v.xy sends fields integer array
+                (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+            } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) { // constant folding for matrices
+                (yyval.interm.intermTypedNode) = context->addConstMatrixNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+            }
+        } else {
+            if ((yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
+                if (((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() || (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getNominalSize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() ) {
+                    context->error((yyvsp[(2) - (4)].lex).line, "", "[", "field selection out of range '%d'", (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+                    context->recover();
+                } else {
+                    if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
+                        if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() == 0) {
+                            if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getMaxArraySize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) {
+                                if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, (yyvsp[(2) - (4)].lex).line))
+                                    context->recover();
+                            } else {
+                                if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), 0, false, (yyvsp[(2) - (4)].lex).line))
+                                    context->recover();
+                            }
+                        } else if ( (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize()) {
+                            context->error((yyvsp[(2) - (4)].lex).line, "", "[", "array index out of range '%d'", (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+                            context->recover();
+                        }
+                    }
+                    (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+                }
+            } else {
+                if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() == 0) {
+                    context->error((yyvsp[(2) - (4)].lex).line, "", "[", "array must be redeclared with a size before being indexed with a variable");
+                    context->recover();
+                }
+
+                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexIndirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+            }
+        }
+        if ((yyval.interm.intermTypedNode) == 0) {
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setFConst(0.0f);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), (yyvsp[(2) - (4)].lex).line);
+        } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
+            if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct())
+                (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getTypeName()));
+            else
+                (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize(), (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()));
+
+            if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
+                (yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst);
+        } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
+            (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqConst, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize()));
+        else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix())
+            (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize()));
+        else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
+            (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqConst));
+        else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector())
+            (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary));
+        else
+            (yyval.interm.intermTypedNode)->setType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType());
+    ;}
+    break;
+
+  case 10:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 11:
+
+    {
+        if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) {
+            context->error((yyvsp[(3) - (3)].lex).line, "cannot apply dot operator to an array", ".", "");
+            context->recover();
+        }
+
+        if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isVector()) {
+            TVectorFields fields;
+            if (! context->parseVectorFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yyvsp[(3) - (3)].lex).line)) {
+                fields.num = 1;
+                fields.offsets[0] = 0;
+                context->recover();
+            }
+
+            if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) { // constant folding for vector fields
+                (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].lex).line);
+                if ((yyval.interm.intermTypedNode) == 0) {
+                    context->recover();
+                    (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+                }
+                else
+                    (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqConst, (int) (*(yyvsp[(3) - (3)].lex).string).size()));
+            } else {
+                if (fields.num == 1) {
+                    ConstantUnion *unionArray = new ConstantUnion[1];
+                    unionArray->setIConst(fields.offsets[0]);
+                    TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
+                    (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                    (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision()));
+                } else {
+                    TString vectorString = *(yyvsp[(3) - (3)].lex).string;
+                    TIntermTyped* index = context->intermediate.addSwizzle(fields, (yyvsp[(3) - (3)].lex).line);
+                    (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpVectorSwizzle, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                    (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (int) vectorString.size()));
+                }
+            }
+        } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isMatrix()) {
+            TMatrixFields fields;
+            if (! context->parseMatrixFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yyvsp[(3) - (3)].lex).line)) {
+                fields.wholeRow = false;
+                fields.wholeCol = false;
+                fields.row = 0;
+                fields.col = 0;
+                context->recover();
+            }
+
+            if (fields.wholeRow || fields.wholeCol) {
+                context->error((yyvsp[(2) - (3)].lex).line, " non-scalar fields not implemented yet", ".", "");
+                context->recover();
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray->setIConst(0);
+                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
+                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(),EvqTemporary, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize()));
+            } else {
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray->setIConst(fields.col * (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize() + fields.row);
+                TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
+                (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision()));
+            }
+        } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType() == EbtStruct) {
+            bool fieldFound = false;
+            const TTypeList* fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct();
+            if (fields == 0) {
+                context->error((yyvsp[(2) - (3)].lex).line, "structure has no fields", "Internal Error", "");
+                context->recover();
+                (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+            } else {
+                unsigned int i;
+                for (i = 0; i < fields->size(); ++i) {
+                    if ((*fields)[i].type->getFieldName() == *(yyvsp[(3) - (3)].lex).string) {
+                        fieldFound = true;
+                        break;
+                    }
+                }
+                if (fieldFound) {
+                    if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) {
+                        (yyval.interm.intermTypedNode) = context->addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+                        if ((yyval.interm.intermTypedNode) == 0) {
+                            context->recover();
+                            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+                        }
+                        else {
+                            (yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
+                            // change the qualifier of the return type, not of the structure field
+                            // as the structure definition is shared between various structures.
+                            (yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst);
+                        }
+                    } else {
+                        ConstantUnion *unionArray = new ConstantUnion[1];
+                        unionArray->setIConst(i);
+                        TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, (yyvsp[(3) - (3)].lex).line);
+                        (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+                        (yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
+                    }
+                } else {
+                    context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str(), "");
+                    context->recover();
+                    (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+                }
+            }
+        } else {
+            context->error((yyvsp[(2) - (3)].lex).line, " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str(), "");
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+        // don't delete $3.string, it's from the pool
+    ;}
+    break;
+
+  case 12:
+
+    {
+        if (context->lValueErrorCheck((yyvsp[(2) - (2)].lex).line, "++", (yyvsp[(1) - (2)].interm.intermTypedNode)))
+            context->recover();
+        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->unaryOpError((yyvsp[(2) - (2)].lex).line, "++", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (2)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 13:
+
+    {
+        if (context->lValueErrorCheck((yyvsp[(2) - (2)].lex).line, "--", (yyvsp[(1) - (2)].interm.intermTypedNode)))
+            context->recover();
+        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->unaryOpError((yyvsp[(2) - (2)].lex).line, "--", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (2)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 14:
+
+    {
+        if (context->integerErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode), "[]"))
+            context->recover();
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 15:
+
+    {
+        TFunction* fnCall = (yyvsp[(1) - (1)].interm).function;
+        TOperator op = fnCall->getBuiltInOp();
+
+        if (op != EOpNull)
+        {
+            //
+            // Then this should be a constructor.
+            // Don't go through the symbol table for constructors.
+            // Their parameters will be verified algorithmically.
+            //
+            TType type(EbtVoid, EbpUndefined);  // use this to get the type back
+            if (context->constructorErrorCheck((yyvsp[(1) - (1)].interm).line, (yyvsp[(1) - (1)].interm).intermNode, *fnCall, op, &type)) {
+                (yyval.interm.intermTypedNode) = 0;
+            } else {
+                //
+                // It's a constructor, of type 'type'.
+                //
+                (yyval.interm.intermTypedNode) = context->addConstructor((yyvsp[(1) - (1)].interm).intermNode, &type, op, fnCall, (yyvsp[(1) - (1)].interm).line);
+            }
+
+            if ((yyval.interm.intermTypedNode) == 0) {
+                context->recover();
+                (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator(0, op, (yyvsp[(1) - (1)].interm).line);
+            }
+            (yyval.interm.intermTypedNode)->setType(type);
+        } else {
+            //
+            // Not a constructor.  Find it in the symbol table.
+            //
+            const TFunction* fnCandidate;
+            bool builtIn;
+            fnCandidate = context->findFunction((yyvsp[(1) - (1)].interm).line, fnCall, &builtIn);
+            if (fnCandidate) {
+                //
+                // A declared function.
+                //
+                if (builtIn && !fnCandidate->getExtension().empty() &&
+                    context->extensionErrorCheck((yyvsp[(1) - (1)].interm).line, fnCandidate->getExtension())) {
+                    context->recover();
+                }
+                op = fnCandidate->getBuiltInOp();
+                if (builtIn && op != EOpNull) {
+                    //
+                    // A function call mapped to a built-in operation.
+                    //
+                    if (fnCandidate->getParamCount() == 1) {
+                        //
+                        // Treat it like a built-in unary operator.
+                        //
+                        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, 0, context->symbolTable);
+                        if ((yyval.interm.intermTypedNode) == 0)  {
+                            context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), " wrong operand type", "Internal Error",
+                                "built in unary operator function.  Type: %s",
+                                static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString().c_str());
+                            YYERROR;
+                        }
+                    } else {
+                        (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yyvsp[(1) - (1)].interm).line);
+                    }
+                } else {
+                    // This is a real function call
+
+                    (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yyvsp[(1) - (1)].interm).line);
+                    (yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
+
+                    // this is how we know whether the given function is a builtIn function or a user defined function
+                    // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
+                    // if builtIn == true, it's definitely a builtIn function with EOpNull
+                    if (!builtIn)
+                        (yyval.interm.intermTypedNode)->getAsAggregate()->setUserDefined();
+                    (yyval.interm.intermTypedNode)->getAsAggregate()->setName(fnCandidate->getMangledName());
+
+                    TQualifier qual;
+                    for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
+                        qual = fnCandidate->getParam(i).type->getQualifier();
+                        if (qual == EvqOut || qual == EvqInOut) {
+                            if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()[i]->getAsTyped())) {
+                                context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
+                                context->recover();
+                            }
+                        }
+                    }
+                }
+                (yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
+            } else {
+                // error message was put out by PaFindFunction()
+                // Put on a dummy node for error recovery
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray->setFConst(0.0f);
+                (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].interm).line);
+                context->recover();
+            }
+        }
+        delete fnCall;
+    ;}
+    break;
+
+  case 16:
+
+    {
+        (yyval.interm) = (yyvsp[(1) - (1)].interm);
+    ;}
+    break;
+
+  case 17:
+
+    {
+        context->error((yyvsp[(3) - (3)].interm).line, "methods are not supported", "", "");
+        context->recover();
+        (yyval.interm) = (yyvsp[(3) - (3)].interm);
+    ;}
+    break;
+
+  case 18:
+
+    {
+        (yyval.interm) = (yyvsp[(1) - (2)].interm);
+        (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
+    ;}
+    break;
+
+  case 19:
+
+    {
+        (yyval.interm) = (yyvsp[(1) - (2)].interm);
+        (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
+    ;}
+    break;
+
+  case 20:
+
+    {
+        (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+        (yyval.interm).intermNode = 0;
+    ;}
+    break;
+
+  case 21:
+
+    {
+        (yyval.interm).function = (yyvsp[(1) - (1)].interm.function);
+        (yyval.interm).intermNode = 0;
+    ;}
+    break;
+
+  case 22:
+
+    {
+        TParameter param = { 0, new TType((yyvsp[(2) - (2)].interm.intermTypedNode)->getType()) };
+        (yyvsp[(1) - (2)].interm.function)->addParameter(param);
+        (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+        (yyval.interm).intermNode = (yyvsp[(2) - (2)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 23:
+
+    {
+        TParameter param = { 0, new TType((yyvsp[(3) - (3)].interm.intermTypedNode)->getType()) };
+        (yyvsp[(1) - (3)].interm).function->addParameter(param);
+        (yyval.interm).function = (yyvsp[(1) - (3)].interm).function;
+        (yyval.interm).intermNode = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+    ;}
+    break;
+
+  case 24:
+
+    {
+        (yyval.interm.function) = (yyvsp[(1) - (2)].interm.function);
+    ;}
+    break;
+
+  case 25:
+
+    {
+        //
+        // Constructor
+        //
+        if ((yyvsp[(1) - (1)].interm.type).array) {
+            // Constructors for arrays are not allowed.
+            context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", "array", "");
+            context->recover();
+            (yyvsp[(1) - (1)].interm.type).setArray(false);
+        }
+
+        TOperator op = EOpNull;
+        if ((yyvsp[(1) - (1)].interm.type).userDef) {
+            op = EOpConstructStruct;
+        } else {
+            switch ((yyvsp[(1) - (1)].interm.type).type) {
+            case EbtFloat:
+                if ((yyvsp[(1) - (1)].interm.type).matrix) {
+                    switch((yyvsp[(1) - (1)].interm.type).size) {
+                    case 2:                                     op = EOpConstructMat2;  break;
+                    case 3:                                     op = EOpConstructMat3;  break;
+                    case 4:                                     op = EOpConstructMat4;  break;
+                    }
+                } else {
+                    switch((yyvsp[(1) - (1)].interm.type).size) {
+                    case 1:                                     op = EOpConstructFloat; break;
+                    case 2:                                     op = EOpConstructVec2;  break;
+                    case 3:                                     op = EOpConstructVec3;  break;
+                    case 4:                                     op = EOpConstructVec4;  break;
+                    }
+                }
+                break;
+            case EbtInt:
+                switch((yyvsp[(1) - (1)].interm.type).size) {
+                case 1:                                         op = EOpConstructInt;   break;
+                case 2:       FRAG_VERT_ONLY("ivec2", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec2; break;
+                case 3:       FRAG_VERT_ONLY("ivec3", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec3; break;
+                case 4:       FRAG_VERT_ONLY("ivec4", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec4; break;
+                }
+                break;
+            case EbtBool:
+                switch((yyvsp[(1) - (1)].interm.type).size) {
+                case 1:                                         op = EOpConstructBool;  break;
+                case 2:       FRAG_VERT_ONLY("bvec2", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec2; break;
+                case 3:       FRAG_VERT_ONLY("bvec3", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec3; break;
+                case 4:       FRAG_VERT_ONLY("bvec4", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec4; break;
+                }
+                break;
+            default: break;
+            }
+            if (op == EOpNull) {
+                context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type), "");
+                context->recover();
+                (yyvsp[(1) - (1)].interm.type).type = EbtFloat;
+                op = EOpConstructFloat;
+            }
+        }
+        TString tempString;
+        TType type((yyvsp[(1) - (1)].interm.type));
+        TFunction *function = new TFunction(&tempString, type, op);
+        (yyval.interm.function) = function;
+    ;}
+    break;
+
+  case 26:
+
+    {
+        if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
+            context->recover();
+        TType type(EbtVoid, EbpUndefined);
+        TFunction *function = new TFunction((yyvsp[(1) - (1)].lex).string, type);
+        (yyval.interm.function) = function;
+    ;}
+    break;
+
+  case 27:
+
+    {
+        if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
+            context->recover();
+        TType type(EbtVoid, EbpUndefined);
+        TFunction *function = new TFunction((yyvsp[(1) - (1)].lex).string, type);
+        (yyval.interm.function) = function;
+    ;}
+    break;
+
+  case 28:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 29:
+
+    {
+        if (context->lValueErrorCheck((yyvsp[(1) - (2)].lex).line, "++", (yyvsp[(2) - (2)].interm.intermTypedNode)))
+            context->recover();
+        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->unaryOpError((yyvsp[(1) - (2)].lex).line, "++", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 30:
+
+    {
+        if (context->lValueErrorCheck((yyvsp[(1) - (2)].lex).line, "--", (yyvsp[(2) - (2)].interm.intermTypedNode)))
+            context->recover();
+        (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->unaryOpError((yyvsp[(1) - (2)].lex).line, "--", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 31:
+
+    {
+        if ((yyvsp[(1) - (2)].interm).op != EOpNull) {
+            (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].interm).line, context->symbolTable);
+            if ((yyval.interm.intermTypedNode) == 0) {
+                const char* errorOp = "";
+                switch((yyvsp[(1) - (2)].interm).op) {
+                case EOpNegative:   errorOp = "-"; break;
+                case EOpLogicalNot: errorOp = "!"; break;
+                default: break;
+                }
+                context->unaryOpError((yyvsp[(1) - (2)].interm).line, errorOp, (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+                context->recover();
+                (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+            }
+        } else
+            (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 32:
+
+    { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpNull; ;}
+    break;
+
+  case 33:
+
+    { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpNegative; ;}
+    break;
+
+  case 34:
+
+    { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpLogicalNot; ;}
+    break;
+
+  case 35:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 36:
+
+    {
+        FRAG_VERT_ONLY("*", (yyvsp[(2) - (3)].lex).line);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "*", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 37:
+
+    {
+        FRAG_VERT_ONLY("/", (yyvsp[(2) - (3)].lex).line);
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "/", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 38:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 39:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "+", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 40:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "-", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 41:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 42:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 43:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "<", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 44:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, ">", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 45:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "<=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 46:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, ">=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 47:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 48:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "==", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 49:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "!=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 50:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 51:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 52:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 53:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 54:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "&&", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 55:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 56:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "^^", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 57:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 58:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, "||", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray->setBConst(false);
+            (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+        }
+    ;}
+    break;
+
+  case 59:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 60:
+
+    {
+       if (context->boolErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(1) - (5)].interm.intermTypedNode)))
+            context->recover();
+
+        (yyval.interm.intermTypedNode) = context->intermediate.addSelection((yyvsp[(1) - (5)].interm.intermTypedNode), (yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.intermTypedNode), (yyvsp[(2) - (5)].lex).line);
+        if ((yyvsp[(3) - (5)].interm.intermTypedNode)->getType() != (yyvsp[(5) - (5)].interm.intermTypedNode)->getType())
+            (yyval.interm.intermTypedNode) = 0;
+
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (5)].lex).line, ":", (yyvsp[(3) - (5)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(5) - (5)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(5) - (5)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 61:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 62:
+
+    {
+        if (context->lValueErrorCheck((yyvsp[(2) - (3)].interm).line, "assign", (yyvsp[(1) - (3)].interm.intermTypedNode)))
+            context->recover();
+        (yyval.interm.intermTypedNode) = context->intermediate.addAssign((yyvsp[(2) - (3)].interm).op, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].interm).line);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->assignError((yyvsp[(2) - (3)].interm).line, "assign", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 63:
+
+    {                                    (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpAssign; ;}
+    break;
+
+  case 64:
+
+    { FRAG_VERT_ONLY("*=", (yyvsp[(1) - (1)].lex).line);     (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpMulAssign; ;}
+    break;
+
+  case 65:
+
+    { FRAG_VERT_ONLY("/=", (yyvsp[(1) - (1)].lex).line);     (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpDivAssign; ;}
+    break;
+
+  case 66:
+
+    {                                    (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpAddAssign; ;}
+    break;
+
+  case 67:
+
+    {                                    (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpSubAssign; ;}
+    break;
+
+  case 68:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 69:
+
+    {
+        (yyval.interm.intermTypedNode) = context->intermediate.addComma((yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context->binaryOpError((yyvsp[(2) - (3)].lex).line, ",", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+            context->recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(3) - (3)].interm.intermTypedNode);
+        }
+    ;}
+    break;
+
+  case 70:
+
+    {
+        if (context->constErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode)))
+            context->recover();
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 71:
+
+    {
+        TFunction &function = *((yyvsp[(1) - (2)].interm).function);
+        
+        TIntermAggregate *prototype = new TIntermAggregate;
+        prototype->setType(function.getReturnType());
+        prototype->setName(function.getName());
+        
+        for (int i = 0; i < function.getParamCount(); i++)
+        {
+            const TParameter &param = function.getParam(i);
+            if (param.name != 0)
+            {
+                TVariable *variable = new TVariable(param.name, *param.type);
+                
+                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), (yyvsp[(1) - (2)].interm).line), (yyvsp[(1) - (2)].interm).line);
+            }
+            else
+            {
+                prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, (yyvsp[(1) - (2)].interm).line), (yyvsp[(1) - (2)].interm).line);
+            }
+        }
+        
+        prototype->setOp(EOpPrototype);
+        (yyval.interm.intermNode) = prototype;
+    ;}
+    break;
+
+  case 72:
+
+    {
+        if ((yyvsp[(1) - (2)].interm).intermAggregate)
+            (yyvsp[(1) - (2)].interm).intermAggregate->setOp(EOpDeclaration);
+        (yyval.interm.intermNode) = (yyvsp[(1) - (2)].interm).intermAggregate;
+    ;}
+    break;
+
+  case 73:
+
+    {
+        context->symbolTable.setDefaultPrecision( (yyvsp[(3) - (4)].interm.type).type, (yyvsp[(2) - (4)].interm.precision) );
+        (yyval.interm.intermNode) = 0;
+    ;}
+    break;
+
+  case 74:
+
+    {
+        //
+        // Multiple declarations of the same function are allowed.
+        //
+        // If this is a definition, the definition production code will check for redefinitions
+        // (we don't know at this point if it's a definition or not).
+        //
+        // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
+        //
+        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName()));
+        if (prevDec) {
+            if (prevDec->getReturnType() != (yyvsp[(1) - (2)].interm.function)->getReturnType()) {
+                context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString(), "");
+                context->recover();
+            }
+            for (int i = 0; i < prevDec->getParamCount(); ++i) {
+                if (prevDec->getParam(i).type->getQualifier() != (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifier()) {
+                    context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same parameter qualifiers", (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifierString(), "");
+                    context->recover();
+                }
+            }
+        }
+
+        //
+        // If this is a redeclaration, it could also be a definition,
+        // in which case, we want to use the variable names from this one, and not the one that's
+        // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
+        //
+        (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+        (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
+
+        context->symbolTable.insert(*(yyval.interm).function);
+    ;}
+    break;
+
+  case 75:
+
+    {
+        (yyval.interm.function) = (yyvsp[(1) - (1)].interm.function);
+    ;}
+    break;
+
+  case 76:
+
+    {
+        (yyval.interm.function) = (yyvsp[(1) - (1)].interm.function);
+    ;}
+    break;
+
+  case 77:
+
+    {
+        // Add the parameter
+        (yyval.interm.function) = (yyvsp[(1) - (2)].interm.function);
+        if ((yyvsp[(2) - (2)].interm).param.type->getBasicType() != EbtVoid)
+            (yyvsp[(1) - (2)].interm.function)->addParameter((yyvsp[(2) - (2)].interm).param);
+        else
+            delete (yyvsp[(2) - (2)].interm).param.type;
+    ;}
+    break;
+
+  case 78:
+
+    {
+        //
+        // Only first parameter of one-parameter functions can be void
+        // The check for named parameters not being void is done in parameter_declarator
+        //
+        if ((yyvsp[(3) - (3)].interm).param.type->getBasicType() == EbtVoid) {
+            //
+            // This parameter > first is void
+            //
+            context->error((yyvsp[(2) - (3)].lex).line, "cannot be an argument type except for '(void)'", "void", "");
+            context->recover();
+            delete (yyvsp[(3) - (3)].interm).param.type;
+        } else {
+            // Add the parameter
+            (yyval.interm.function) = (yyvsp[(1) - (3)].interm.function);
+            (yyvsp[(1) - (3)].interm.function)->addParameter((yyvsp[(3) - (3)].interm).param);
+        }
+    ;}
+    break;
+
+  case 79:
+
+    {
+        if ((yyvsp[(1) - (3)].interm.type).qualifier != EvqGlobal && (yyvsp[(1) - (3)].interm.type).qualifier != EvqTemporary) {
+            context->error((yyvsp[(2) - (3)].lex).line, "no qualifiers allowed for function return", getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier), "");
+            context->recover();
+        }
+        // make sure a sampler is not involved as well...
+        if (context->structQualifierErrorCheck((yyvsp[(2) - (3)].lex).line, (yyvsp[(1) - (3)].interm.type)))
+            context->recover();
+
+        // Add the function as a prototype after parsing it (we do not support recursion)
+        TFunction *function;
+        TType type((yyvsp[(1) - (3)].interm.type));
+        function = new TFunction((yyvsp[(2) - (3)].lex).string, type);
+        (yyval.interm.function) = function;
+    ;}
+    break;
+
+  case 80:
+
+    {
+        if ((yyvsp[(1) - (2)].interm.type).type == EbtVoid) {
+            context->error((yyvsp[(2) - (2)].lex).line, "illegal use of type 'void'", (yyvsp[(2) - (2)].lex).string->c_str(), "");
+            context->recover();
+        }
+        if (context->reservedErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string))
+            context->recover();
+        TParameter param = {(yyvsp[(2) - (2)].lex).string, new TType((yyvsp[(1) - (2)].interm.type))};
+        (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
+        (yyval.interm).param = param;
+    ;}
+    break;
+
+  case 81:
+
+    {
+        // Check that we can make an array out of this type
+        if (context->arrayTypeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+            context->recover();
+
+        if (context->reservedErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string))
+            context->recover();
+
+        int size;
+        if (context->arraySizeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+            context->recover();
+        (yyvsp[(1) - (5)].interm.type).setArray(true, size);
+
+        TType* type = new TType((yyvsp[(1) - (5)].interm.type));
+        TParameter param = { (yyvsp[(2) - (5)].lex).string, type };
+        (yyval.interm).line = (yyvsp[(2) - (5)].lex).line;
+        (yyval.interm).param = param;
+    ;}
+    break;
+
+  case 82:
+
+    {
+        (yyval.interm) = (yyvsp[(3) - (3)].interm);
+        if (context->paramErrorCheck((yyvsp[(3) - (3)].interm).line, (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
+            context->recover();
+    ;}
+    break;
+
+  case 83:
+
+    {
+        (yyval.interm) = (yyvsp[(2) - (2)].interm);
+        if (context->parameterSamplerErrorCheck((yyvsp[(2) - (2)].interm).line, (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
+            context->recover();
+        if (context->paramErrorCheck((yyvsp[(2) - (2)].interm).line, EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
+            context->recover();
+    ;}
+    break;
+
+  case 84:
+
+    {
+        (yyval.interm) = (yyvsp[(3) - (3)].interm);
+        if (context->paramErrorCheck((yyvsp[(3) - (3)].interm).line, (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
+            context->recover();
+    ;}
+    break;
+
+  case 85:
+
+    {
+        (yyval.interm) = (yyvsp[(2) - (2)].interm);
+        if (context->parameterSamplerErrorCheck((yyvsp[(2) - (2)].interm).line, (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
+            context->recover();
+        if (context->paramErrorCheck((yyvsp[(2) - (2)].interm).line, EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
+            context->recover();
+    ;}
+    break;
+
+  case 86:
+
+    {
+        (yyval.interm.qualifier) = EvqIn;
+    ;}
+    break;
+
+  case 87:
+
+    {
+        (yyval.interm.qualifier) = EvqIn;
+    ;}
+    break;
+
+  case 88:
+
+    {
+        (yyval.interm.qualifier) = EvqOut;
+    ;}
+    break;
+
+  case 89:
+
+    {
+        (yyval.interm.qualifier) = EvqInOut;
+    ;}
+    break;
+
+  case 90:
+
+    {
+        TParameter param = { 0, new TType((yyvsp[(1) - (1)].interm.type)) };
+        (yyval.interm).param = param;
+    ;}
+    break;
+
+  case 91:
+
+    {
+        (yyval.interm) = (yyvsp[(1) - (1)].interm);
+        
+        if ((yyval.interm).type.precision == EbpUndefined) {
+            (yyval.interm).type.precision = context->symbolTable.getDefaultPrecision((yyvsp[(1) - (1)].interm).type.type);
+            if (context->precisionErrorCheck((yyvsp[(1) - (1)].interm).line, (yyval.interm).type.precision, (yyvsp[(1) - (1)].interm).type.type)) {
+                context->recover();
+            }
+        }
+    ;}
+    break;
+
+  case 92:
+
+    {
+        (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, context->intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yyvsp[(3) - (3)].lex).line), (yyvsp[(3) - (3)].lex).line);
+        
+        if (context->structQualifierErrorCheck((yyvsp[(3) - (3)].lex).line, (yyval.interm).type))
+            context->recover();
+
+        if (context->nonInitConstErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type))
+            context->recover();
+
+        if (context->nonInitErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type))
+            context->recover();
+    ;}
+    break;
+
+  case 93:
+
+    {
+        if (context->structQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+            context->recover();
+
+        if (context->nonInitConstErrorCheck((yyvsp[(3) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type))
+            context->recover();
+
+        (yyval.interm) = (yyvsp[(1) - (5)].interm);
+
+        if (context->arrayTypeErrorCheck((yyvsp[(4) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type) || context->arrayQualifierErrorCheck((yyvsp[(4) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+            context->recover();
+        else {
+            (yyvsp[(1) - (5)].interm).type.setArray(true);
+            TVariable* variable;
+            if (context->arrayErrorCheck((yyvsp[(4) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, variable))
+                context->recover();
+        }
+    ;}
+    break;
+
+  case 94:
+
+    {
+        if (context->structQualifierErrorCheck((yyvsp[(3) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type))
+            context->recover();
+
+        if (context->nonInitConstErrorCheck((yyvsp[(3) - (6)].lex).line, *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type))
+            context->recover();
+
+        (yyval.interm) = (yyvsp[(1) - (6)].interm);
+
+        if (context->arrayTypeErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type) || context->arrayQualifierErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type))
+            context->recover();
+        else {
+            int size;
+            if (context->arraySizeErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(5) - (6)].interm.intermTypedNode), size))
+                context->recover();
+            (yyvsp[(1) - (6)].interm).type.setArray(true, size);
+            TVariable* variable;
+            if (context->arrayErrorCheck((yyvsp[(4) - (6)].lex).line, *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, variable))
+                context->recover();
+            TType type = TType((yyvsp[(1) - (6)].interm).type);
+            type.setArraySize(size);
+            (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context->intermediate.addSymbol(0, *(yyvsp[(3) - (6)].lex).string, type, (yyvsp[(3) - (6)].lex).line), (yyvsp[(3) - (6)].lex).line);
+        }
+    ;}
+    break;
+
+  case 95:
+
+    {
+        if (context->structQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+            context->recover();
+
+        (yyval.interm) = (yyvsp[(1) - (5)].interm);
+
+        TIntermNode* intermNode;
+        if (!context->executeInitializer((yyvsp[(3) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, (yyvsp[(5) - (5)].interm.intermTypedNode), intermNode)) {
+            //
+            // build the intermediate representation
+            //
+            if (intermNode)
+        (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (5)].interm).intermNode, intermNode, (yyvsp[(4) - (5)].lex).line);
+            else
+                (yyval.interm).intermAggregate = (yyvsp[(1) - (5)].interm).intermAggregate;
+        } else {
+            context->recover();
+            (yyval.interm).intermAggregate = 0;
+        }
+    ;}
+    break;
+
+  case 96:
+
+    {
+        (yyval.interm).type = (yyvsp[(1) - (1)].interm.type);
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType((yyvsp[(1) - (1)].interm.type)), (yyvsp[(1) - (1)].interm.type).line), (yyvsp[(1) - (1)].interm.type).line);
+    ;}
+    break;
+
+  case 97:
+
+    {
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yyvsp[(2) - (2)].lex).line), (yyvsp[(2) - (2)].lex).line);
+        
+        if (context->structQualifierErrorCheck((yyvsp[(2) - (2)].lex).line, (yyval.interm).type))
+            context->recover();
+
+        if (context->nonInitConstErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type))
+            context->recover();
+            
+            (yyval.interm).type = (yyvsp[(1) - (2)].interm.type);
+
+        if (context->nonInitErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type))
+            context->recover();
+    ;}
+    break;
+
+  case 98:
+
+    {
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line), (yyvsp[(2) - (4)].lex).line);
+        
+        if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+            context->recover();
+
+        if (context->nonInitConstErrorCheck((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type)))
+            context->recover();
+
+        (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
+
+        if (context->arrayTypeErrorCheck((yyvsp[(3) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)) || context->arrayQualifierErrorCheck((yyvsp[(3) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+            context->recover();
+        else {
+            (yyvsp[(1) - (4)].interm.type).setArray(true);
+            TVariable* variable;
+            if (context->arrayErrorCheck((yyvsp[(3) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), variable))
+                context->recover();
+        }
+    ;}
+    break;
+
+  case 99:
+
+    {
+        TType type = TType((yyvsp[(1) - (5)].interm.type));
+        int size;
+        if (context->arraySizeErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+            context->recover();
+        type.setArraySize(size);
+        (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yyvsp[(2) - (5)].lex).line), (yyvsp[(2) - (5)].lex).line);
+        
+        if (context->structQualifierErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+            context->recover();
+
+        if (context->nonInitConstErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type)))
+            context->recover();
+
+        (yyval.interm).type = (yyvsp[(1) - (5)].interm.type);
+
+        if (context->arrayTypeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)) || context->arrayQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+            context->recover();
+        else {
+            int size;
+            if (context->arraySizeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+                context->recover();
+
+            (yyvsp[(1) - (5)].interm.type).setArray(true, size);
+            TVariable* variable;
+            if (context->arrayErrorCheck((yyvsp[(3) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), variable))
+                context->recover();
+        }
+    ;}
+    break;
+
+  case 100:
+
+    {
+        if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+            context->recover();
+
+        (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
+
+        TIntermNode* intermNode;
+        if (!context->executeInitializer((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode)) {
+        //
+        // Build intermediate representation
+        //
+            if(intermNode)
+                (yyval.interm).intermAggregate = context->intermediate.makeAggregate(intermNode, (yyvsp[(3) - (4)].lex).line);
+            else
+                (yyval.interm).intermAggregate = 0;
+        } else {
+            context->recover();
+            (yyval.interm).intermAggregate = 0;
+        }
+    ;}
+    break;
+
+  case 101:
+
+    {
+        VERTEX_ONLY("invariant declaration", (yyvsp[(1) - (2)].lex).line);
+        (yyval.interm).qualifier = EvqInvariantVaryingOut;
+        (yyval.interm).intermAggregate = 0;
+    ;}
+    break;
+
+  case 102:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+
+        if ((yyvsp[(1) - (1)].interm.type).array) {
+            context->error((yyvsp[(1) - (1)].interm.type).line, "not supported", "first-class array", "");
+            context->recover();
+            (yyvsp[(1) - (1)].interm.type).setArray(false);
+        }
+    ;}
+    break;
+
+  case 103:
+
+    {
+        if ((yyvsp[(2) - (2)].interm.type).array) {
+            context->error((yyvsp[(2) - (2)].interm.type).line, "not supported", "first-class array", "");
+            context->recover();
+            (yyvsp[(2) - (2)].interm.type).setArray(false);
+        }
+
+        if ((yyvsp[(1) - (2)].interm.type).qualifier == EvqAttribute &&
+            ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
+            context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier), "");
+            context->recover();
+        }
+        if (((yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingIn || (yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingOut) &&
+            ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
+            context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier), "");
+            context->recover();
+        }
+        (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type);
+        (yyval.interm.type).qualifier = (yyvsp[(1) - (2)].interm.type).qualifier;
+    ;}
+    break;
+
+  case 104:
+
+    {
+        (yyval.interm.type).setBasic(EbtVoid, EvqConst, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 105:
+
+    {
+        VERTEX_ONLY("attribute", (yyvsp[(1) - (1)].lex).line);
+        if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "attribute"))
+            context->recover();
+        (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 106:
+
+    {
+        if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "varying"))
+            context->recover();
+        if (context->shaderType == SH_VERTEX_SHADER)
+            (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yyvsp[(1) - (1)].lex).line);
+        else
+            (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 107:
+
+    {
+        if (context->globalErrorCheck((yyvsp[(1) - (2)].lex).line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+            context->recover();
+        if (context->shaderType == SH_VERTEX_SHADER)
+            (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingOut, (yyvsp[(1) - (2)].lex).line);
+        else
+            (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingIn, (yyvsp[(1) - (2)].lex).line);
+    ;}
+    break;
+
+  case 108:
+
+    {
+        if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "uniform"))
+            context->recover();
+        (yyval.interm.type).setBasic(EbtVoid, EvqUniform, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 109:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+    ;}
+    break;
+
+  case 110:
+
+    {
+        (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type);
+        (yyval.interm.type).precision = (yyvsp[(1) - (2)].interm.precision);
+    ;}
+    break;
+
+  case 111:
+
+    {
+        (yyval.interm.precision) = EbpHigh;
+    ;}
+    break;
+
+  case 112:
+
+    {
+        (yyval.interm.precision) = EbpMedium;
+    ;}
+    break;
+
+  case 113:
+
+    {
+        (yyval.interm.precision) = EbpLow;
+    ;}
+    break;
+
+  case 114:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+    ;}
+    break;
+
+  case 115:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (4)].interm.type);
+
+        if (context->arrayTypeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+            context->recover();
+        else {
+            int size;
+            if (context->arraySizeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+                context->recover();
+            (yyval.interm.type).setArray(true, size);
+        }
+    ;}
+    break;
+
+  case 116:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtVoid, qual, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 117:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 118:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 119:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 120:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(2);
+    ;}
+    break;
+
+  case 121:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(3);
+    ;}
+    break;
+
+  case 122:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(4);
+    ;}
+    break;
+
+  case 123:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(2);
+    ;}
+    break;
+
+  case 124:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(3);
+    ;}
+    break;
+
+  case 125:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(4);
+    ;}
+    break;
+
+  case 126:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(2);
+    ;}
+    break;
+
+  case 127:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(3);
+    ;}
+    break;
+
+  case 128:
+
+    {
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(4);
+    ;}
+    break;
+
+  case 129:
+
+    {
+        FRAG_VERT_ONLY("mat2", (yyvsp[(1) - (1)].lex).line);
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(2, true);
+    ;}
+    break;
+
+  case 130:
+
+    {
+        FRAG_VERT_ONLY("mat3", (yyvsp[(1) - (1)].lex).line);
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(3, true);
+    ;}
+    break;
+
+  case 131:
+
+    {
+        FRAG_VERT_ONLY("mat4", (yyvsp[(1) - (1)].lex).line);
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).setAggregate(4, true);
+    ;}
+    break;
+
+  case 132:
+
+    {
+        FRAG_VERT_ONLY("sampler2D", (yyvsp[(1) - (1)].lex).line);
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtSampler2D, qual, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 133:
+
+    {
+        FRAG_VERT_ONLY("samplerCube", (yyvsp[(1) - (1)].lex).line);
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtSamplerCube, qual, (yyvsp[(1) - (1)].lex).line);
+    ;}
+    break;
+
+  case 134:
+
+    {
+        FRAG_VERT_ONLY("struct", (yyvsp[(1) - (1)].interm.type).line);
+        (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+        (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+    ;}
+    break;
+
+  case 135:
+
+    {
+        //
+        // This is for user defined type names.  The lexical phase looked up the
+        // type.
+        //
+        TType& structure = static_cast<TVariable*>((yyvsp[(1) - (1)].lex).symbol)->getType();
+        TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtStruct, qual, (yyvsp[(1) - (1)].lex).line);
+        (yyval.interm.type).userDef = &structure;
+    ;}
+    break;
+
+  case 136:
+
+    {
+        if (context->reservedErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string))
+            context->recover();
+
+        TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), *(yyvsp[(2) - (5)].lex).string);
+        TVariable* userTypeDef = new TVariable((yyvsp[(2) - (5)].lex).string, *structure, true);
+        if (! context->symbolTable.insert(*userTypeDef)) {
+            context->error((yyvsp[(2) - (5)].lex).line, "redefinition", (yyvsp[(2) - (5)].lex).string->c_str(), "struct");
+            context->recover();
+        }
+        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line);
+        (yyval.interm.type).userDef = structure;
+    ;}
+    break;
+
+  case 137:
+
+    {
+        TType* structure = new TType((yyvsp[(3) - (4)].interm.typeList), TString(""));
+        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (4)].lex).line);
+        (yyval.interm.type).userDef = structure;
+    ;}
+    break;
+
+  case 138:
+
+    {
+        (yyval.interm.typeList) = (yyvsp[(1) - (1)].interm.typeList);
+    ;}
+    break;
+
+  case 139:
+
+    {
+        (yyval.interm.typeList) = (yyvsp[(1) - (2)].interm.typeList);
+        for (unsigned int i = 0; i < (yyvsp[(2) - (2)].interm.typeList)->size(); ++i) {
+            for (unsigned int j = 0; j < (yyval.interm.typeList)->size(); ++j) {
+                if ((*(yyval.interm.typeList))[j].type->getFieldName() == (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName()) {
+                    context->error((*(yyvsp[(2) - (2)].interm.typeList))[i].line, "duplicate field name in structure:", "struct", (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName().c_str());
+                    context->recover();
+                }
+            }
+            (yyval.interm.typeList)->push_back((*(yyvsp[(2) - (2)].interm.typeList))[i]);
+        }
+    ;}
+    break;
+
+  case 140:
+
+    {
+        (yyval.interm.typeList) = (yyvsp[(2) - (3)].interm.typeList);
+
+        if (context->voidErrorCheck((yyvsp[(1) - (3)].interm.type).line, (*(yyvsp[(2) - (3)].interm.typeList))[0].type->getFieldName(), (yyvsp[(1) - (3)].interm.type))) {
+            context->recover();
+        }
+        for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) {
+            //
+            // Careful not to replace already known aspects of type, like array-ness
+            //
+            TType* type = (*(yyval.interm.typeList))[i].type;
+            type->setBasicType((yyvsp[(1) - (3)].interm.type).type);
+            type->setNominalSize((yyvsp[(1) - (3)].interm.type).size);
+            type->setMatrix((yyvsp[(1) - (3)].interm.type).matrix);
+
+            // don't allow arrays of arrays
+            if (type->isArray()) {
+                if (context->arrayTypeErrorCheck((yyvsp[(1) - (3)].interm.type).line, (yyvsp[(1) - (3)].interm.type)))
+                    context->recover();
+            }
+            if ((yyvsp[(1) - (3)].interm.type).array)
+                type->setArraySize((yyvsp[(1) - (3)].interm.type).arraySize);
+            if ((yyvsp[(1) - (3)].interm.type).userDef) {
+                type->setStruct((yyvsp[(1) - (3)].interm.type).userDef->getStruct());
+                type->setTypeName((yyvsp[(1) - (3)].interm.type).userDef->getTypeName());
+            }
+        }
+    ;}
+    break;
+
+  case 141:
+
+    {
+        (yyval.interm.typeList) = NewPoolTTypeList();
+        (yyval.interm.typeList)->push_back((yyvsp[(1) - (1)].interm.typeLine));
+    ;}
+    break;
+
+  case 142:
+
+    {
+        (yyval.interm.typeList)->push_back((yyvsp[(3) - (3)].interm.typeLine));
+    ;}
+    break;
+
+  case 143:
+
+    {
+        if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
+            context->recover();
+
+        (yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined);
+        (yyval.interm.typeLine).line = (yyvsp[(1) - (1)].lex).line;
+        (yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (1)].lex).string);
+    ;}
+    break;
+
+  case 144:
+
+    {
+        if (context->reservedErrorCheck((yyvsp[(1) - (4)].lex).line, *(yyvsp[(1) - (4)].lex).string))
+            context->recover();
+
+        (yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined);
+        (yyval.interm.typeLine).line = (yyvsp[(1) - (4)].lex).line;
+        (yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (4)].lex).string);
+
+        int size;
+        if (context->arraySizeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+            context->recover();
+        (yyval.interm.typeLine).type->setArraySize(size);
+    ;}
+    break;
+
+  case 145:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+    break;
+
+  case 146:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 147:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); ;}
+    break;
+
+  case 148:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 149:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 150:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 151:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 152:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 153:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 154:
+
+    { (yyval.interm.intermAggregate) = 0; ;}
+    break;
+
+  case 155:
+
+    { context->symbolTable.push(); ;}
+    break;
+
+  case 156:
+
+    { context->symbolTable.pop(); ;}
+    break;
+
+  case 157:
+
+    {
+        if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0)
+            (yyvsp[(3) - (5)].interm.intermAggregate)->setOp(EOpSequence);
+        (yyval.interm.intermAggregate) = (yyvsp[(3) - (5)].interm.intermAggregate);
+    ;}
+    break;
+
+  case 158:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 159:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+    break;
+
+  case 160:
+
+    {
+        (yyval.interm.intermNode) = 0;
+    ;}
+    break;
+
+  case 161:
+
+    {
+        if ((yyvsp[(2) - (3)].interm.intermAggregate))
+            (yyvsp[(2) - (3)].interm.intermAggregate)->setOp(EOpSequence);
+        (yyval.interm.intermNode) = (yyvsp[(2) - (3)].interm.intermAggregate);
+    ;}
+    break;
+
+  case 162:
+
+    {
+        (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), 0);
+    ;}
+    break;
+
+  case 163:
+
+    {
+        (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), 0);
+    ;}
+    break;
+
+  case 164:
+
+    { (yyval.interm.intermNode) = 0; ;}
+    break;
+
+  case 165:
+
+    { (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[(1) - (2)].interm.intermTypedNode)); ;}
+    break;
+
+  case 166:
+
+    {
+        if (context->boolErrorCheck((yyvsp[(1) - (5)].lex).line, (yyvsp[(3) - (5)].interm.intermTypedNode)))
+            context->recover();
+        (yyval.interm.intermNode) = context->intermediate.addSelection((yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.nodePair), (yyvsp[(1) - (5)].lex).line);
+    ;}
+    break;
+
+  case 167:
+
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermNode);
+        (yyval.interm.nodePair).node2 = (yyvsp[(3) - (3)].interm.intermNode);
+    ;}
+    break;
+
+  case 168:
+
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[(1) - (1)].interm.intermNode);
+        (yyval.interm.nodePair).node2 = 0;
+    ;}
+    break;
+
+  case 169:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+        if (context->boolErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode)->getLine(), (yyvsp[(1) - (1)].interm.intermTypedNode)))
+            context->recover();
+    ;}
+    break;
+
+  case 170:
+
+    {
+        TIntermNode* intermNode;
+        if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+            context->recover();
+        if (context->boolErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+            context->recover();
+
+        if (!context->executeInitializer((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode))
+            (yyval.interm.intermTypedNode) = (yyvsp[(4) - (4)].interm.intermTypedNode);
+        else {
+            context->recover();
+            (yyval.interm.intermTypedNode) = 0;
+        }
+    ;}
+    break;
+
+  case 171:
+
+    { context->symbolTable.push(); ++context->loopNestingLevel; ;}
+    break;
+
+  case 172:
+
+    {
+        context->symbolTable.pop();
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopWhile, 0, (yyvsp[(4) - (6)].interm.intermTypedNode), 0, (yyvsp[(6) - (6)].interm.intermNode), (yyvsp[(1) - (6)].lex).line);
+        --context->loopNestingLevel;
+    ;}
+    break;
+
+  case 173:
+
+    { ++context->loopNestingLevel; ;}
+    break;
+
+  case 174:
+
+    {
+        if (context->boolErrorCheck((yyvsp[(8) - (8)].lex).line, (yyvsp[(6) - (8)].interm.intermTypedNode)))
+            context->recover();
+
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[(6) - (8)].interm.intermTypedNode), 0, (yyvsp[(3) - (8)].interm.intermNode), (yyvsp[(4) - (8)].lex).line);
+        --context->loopNestingLevel;
+    ;}
+    break;
+
+  case 175:
+
+    { context->symbolTable.push(); ++context->loopNestingLevel; ;}
+    break;
+
+  case 176:
+
+    {
+        context->symbolTable.pop();
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yyvsp[(1) - (7)].lex).line);
+        --context->loopNestingLevel;
+    ;}
+    break;
+
+  case 177:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    ;}
+    break;
+
+  case 178:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    ;}
+    break;
+
+  case 179:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 180:
+
+    {
+        (yyval.interm.intermTypedNode) = 0;
+    ;}
+    break;
+
+  case 181:
+
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[(1) - (2)].interm.intermTypedNode);
+        (yyval.interm.nodePair).node2 = 0;
+    ;}
+    break;
+
+  case 182:
+
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        (yyval.interm.nodePair).node2 = (yyvsp[(3) - (3)].interm.intermTypedNode);
+    ;}
+    break;
+
+  case 183:
+
+    {
+        if (context->loopNestingLevel <= 0) {
+            context->error((yyvsp[(1) - (2)].lex).line, "continue statement only allowed in loops", "", "");
+            context->recover();
+        }
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpContinue, (yyvsp[(1) - (2)].lex).line);
+    ;}
+    break;
+
+  case 184:
+
+    {
+        if (context->loopNestingLevel <= 0) {
+            context->error((yyvsp[(1) - (2)].lex).line, "break statement only allowed in loops", "", "");
+            context->recover();
+        }
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpBreak, (yyvsp[(1) - (2)].lex).line);
+    ;}
+    break;
+
+  case 185:
+
+    {
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line);
+        if (context->currentFunctionType->getBasicType() != EbtVoid) {
+            context->error((yyvsp[(1) - (2)].lex).line, "non-void function must return a value", "return", "");
+            context->recover();
+        }
+    ;}
+    break;
+
+  case 186:
+
+    {
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line);
+        context->functionReturnsValue = true;
+        if (context->currentFunctionType->getBasicType() == EbtVoid) {
+            context->error((yyvsp[(1) - (3)].lex).line, "void function cannot return a value", "return", "");
+            context->recover();
+        } else if (*(context->currentFunctionType) != (yyvsp[(2) - (3)].interm.intermTypedNode)->getType()) {
+            context->error((yyvsp[(1) - (3)].lex).line, "function return is not matching type:", "return", "");
+            context->recover();
+        }
+    ;}
+    break;
+
+  case 187:
+
+    {
+        FRAG_ONLY("discard", (yyvsp[(1) - (2)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addBranch(EOpKill, (yyvsp[(1) - (2)].lex).line);
+    ;}
+    break;
+
+  case 188:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+        context->treeRoot = (yyval.interm.intermNode);
+    ;}
+    break;
+
+  case 189:
+
+    {
+        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), 0);
+        context->treeRoot = (yyval.interm.intermNode);
+    ;}
+    break;
+
+  case 190:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    ;}
+    break;
+
+  case 191:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    ;}
+    break;
+
+  case 192:
+
+    {
+        TFunction* function = (yyvsp[(1) - (1)].interm).function;
+        TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
+        //
+        // Note:  'prevDec' could be 'function' if this is the first time we've seen function
+        // as it would have just been put in the symbol table.  Otherwise, we're looking up
+        // an earlier occurance.
+        //
+        if (prevDec->isDefined()) {
+            //
+            // Then this function already has a body.
+            //
+            context->error((yyvsp[(1) - (1)].interm).line, "function already has a body", function->getName().c_str(), "");
+            context->recover();
+        }
+        prevDec->setDefined();
+
+        //
+        // Raise error message if main function takes any parameters or return anything other than void
+        //
+        if (function->getName() == "main") {
+            if (function->getParamCount() > 0) {
+                context->error((yyvsp[(1) - (1)].interm).line, "function cannot take any parameter(s)", function->getName().c_str(), "");
+                context->recover();
+            }
+            if (function->getReturnType().getBasicType() != EbtVoid) {
+                context->error((yyvsp[(1) - (1)].interm).line, "", function->getReturnType().getBasicString(), "main function cannot return a value");
+                context->recover();
+            }
+        }
+
+        //
+        // New symbol table scope for body of function plus its arguments
+        //
+        context->symbolTable.push();
+
+        //
+        // Remember the return type for later checking for RETURN statements.
+        //
+        context->currentFunctionType = &(prevDec->getReturnType());
+        context->functionReturnsValue = false;
+
+        //
+        // Insert parameters into the symbol table.
+        // If the parameter has no name, it's not an error, just don't insert it
+        // (could be used for unused args).
+        //
+        // Also, accumulate the list of parameters into the HIL, so lower level code
+        // knows where to find parameters.
+        //
+        TIntermAggregate* paramNodes = new TIntermAggregate;
+        for (int i = 0; i < function->getParamCount(); i++) {
+            const TParameter& param = function->getParam(i);
+            if (param.name != 0) {
+                TVariable *variable = new TVariable(param.name, *param.type);
+                //
+                // Insert the parameters with name in the symbol table.
+                //
+                if (! context->symbolTable.insert(*variable)) {
+                    context->error((yyvsp[(1) - (1)].interm).line, "redefinition", variable->getName().c_str(), "");
+                    context->recover();
+                    delete variable;
+                }
+
+                //
+                // Add the parameter to the HIL
+                //
+                paramNodes = context->intermediate.growAggregate(
+                                               paramNodes,
+                                               context->intermediate.addSymbol(variable->getUniqueId(),
+                                                                       variable->getName(),
+                                                                       variable->getType(), (yyvsp[(1) - (1)].interm).line),
+                                               (yyvsp[(1) - (1)].interm).line);
+            } else {
+                paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, (yyvsp[(1) - (1)].interm).line), (yyvsp[(1) - (1)].interm).line);
+            }
+        }
+        context->intermediate.setAggregateOperator(paramNodes, EOpParameters, (yyvsp[(1) - (1)].interm).line);
+        (yyvsp[(1) - (1)].interm).intermAggregate = paramNodes;
+        context->loopNestingLevel = 0;
+    ;}
+    break;
+
+  case 193:
+
+    {
+        //?? Check that all paths return a value if return type != void ?
+        //   May be best done as post process phase on intermediate code
+        if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
+            context->error((yyvsp[(1) - (3)].interm).line, "function does not return a value:", "", (yyvsp[(1) - (3)].interm).function->getName().c_str());
+            context->recover();
+        }
+        context->symbolTable.pop();
+        (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermAggregate, (yyvsp[(3) - (3)].interm.intermNode), 0);
+        context->intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yyvsp[(1) - (3)].interm).line);
+        (yyval.interm.intermNode)->getAsAggregate()->setName((yyvsp[(1) - (3)].interm).function->getMangledName().c_str());
+        (yyval.interm.intermNode)->getAsAggregate()->setType((yyvsp[(1) - (3)].interm).function->getReturnType());
+
+        // store the pragma information for debug and optimize and other vendor specific
+        // information. This information can be queried from the parse tree
+        (yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->contextPragma.optimize);
+        (yyval.interm.intermNode)->getAsAggregate()->setDebug(context->contextPragma.debug);
+        (yyval.interm.intermNode)->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
+    ;}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (context, YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (context, yymsg);
+	  }
+	else
+	  {
+	    yyerror (context, YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
+      else
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval, context);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp, context);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (context, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval, context);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp, context);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
+
+
+int glslang_parse(TParseContext* context) {
+    return yyparse(context);
+}
+
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h
new file mode 100644
index 0000000..05cbfd4
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h
@@ -0,0 +1,274 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     INVARIANT = 258,
+     HIGH_PRECISION = 259,
+     MEDIUM_PRECISION = 260,
+     LOW_PRECISION = 261,
+     PRECISION = 262,
+     ATTRIBUTE = 263,
+     CONST_QUAL = 264,
+     BOOL_TYPE = 265,
+     FLOAT_TYPE = 266,
+     INT_TYPE = 267,
+     BREAK = 268,
+     CONTINUE = 269,
+     DO = 270,
+     ELSE = 271,
+     FOR = 272,
+     IF = 273,
+     DISCARD = 274,
+     RETURN = 275,
+     BVEC2 = 276,
+     BVEC3 = 277,
+     BVEC4 = 278,
+     IVEC2 = 279,
+     IVEC3 = 280,
+     IVEC4 = 281,
+     VEC2 = 282,
+     VEC3 = 283,
+     VEC4 = 284,
+     MATRIX2 = 285,
+     MATRIX3 = 286,
+     MATRIX4 = 287,
+     IN_QUAL = 288,
+     OUT_QUAL = 289,
+     INOUT_QUAL = 290,
+     UNIFORM = 291,
+     VARYING = 292,
+     STRUCT = 293,
+     VOID_TYPE = 294,
+     WHILE = 295,
+     SAMPLER2D = 296,
+     SAMPLERCUBE = 297,
+     IDENTIFIER = 298,
+     TYPE_NAME = 299,
+     FLOATCONSTANT = 300,
+     INTCONSTANT = 301,
+     BOOLCONSTANT = 302,
+     FIELD_SELECTION = 303,
+     LEFT_OP = 304,
+     RIGHT_OP = 305,
+     INC_OP = 306,
+     DEC_OP = 307,
+     LE_OP = 308,
+     GE_OP = 309,
+     EQ_OP = 310,
+     NE_OP = 311,
+     AND_OP = 312,
+     OR_OP = 313,
+     XOR_OP = 314,
+     MUL_ASSIGN = 315,
+     DIV_ASSIGN = 316,
+     ADD_ASSIGN = 317,
+     MOD_ASSIGN = 318,
+     LEFT_ASSIGN = 319,
+     RIGHT_ASSIGN = 320,
+     AND_ASSIGN = 321,
+     XOR_ASSIGN = 322,
+     OR_ASSIGN = 323,
+     SUB_ASSIGN = 324,
+     LEFT_PAREN = 325,
+     RIGHT_PAREN = 326,
+     LEFT_BRACKET = 327,
+     RIGHT_BRACKET = 328,
+     LEFT_BRACE = 329,
+     RIGHT_BRACE = 330,
+     DOT = 331,
+     COMMA = 332,
+     COLON = 333,
+     EQUAL = 334,
+     SEMICOLON = 335,
+     BANG = 336,
+     DASH = 337,
+     TILDE = 338,
+     PLUS = 339,
+     STAR = 340,
+     SLASH = 341,
+     PERCENT = 342,
+     LEFT_ANGLE = 343,
+     RIGHT_ANGLE = 344,
+     VERTICAL_BAR = 345,
+     CARET = 346,
+     AMPERSAND = 347,
+     QUESTION = 348
+   };
+#endif
+/* Tokens.  */
+#define INVARIANT 258
+#define HIGH_PRECISION 259
+#define MEDIUM_PRECISION 260
+#define LOW_PRECISION 261
+#define PRECISION 262
+#define ATTRIBUTE 263
+#define CONST_QUAL 264
+#define BOOL_TYPE 265
+#define FLOAT_TYPE 266
+#define INT_TYPE 267
+#define BREAK 268
+#define CONTINUE 269
+#define DO 270
+#define ELSE 271
+#define FOR 272
+#define IF 273
+#define DISCARD 274
+#define RETURN 275
+#define BVEC2 276
+#define BVEC3 277
+#define BVEC4 278
+#define IVEC2 279
+#define IVEC3 280
+#define IVEC4 281
+#define VEC2 282
+#define VEC3 283
+#define VEC4 284
+#define MATRIX2 285
+#define MATRIX3 286
+#define MATRIX4 287
+#define IN_QUAL 288
+#define OUT_QUAL 289
+#define INOUT_QUAL 290
+#define UNIFORM 291
+#define VARYING 292
+#define STRUCT 293
+#define VOID_TYPE 294
+#define WHILE 295
+#define SAMPLER2D 296
+#define SAMPLERCUBE 297
+#define IDENTIFIER 298
+#define TYPE_NAME 299
+#define FLOATCONSTANT 300
+#define INTCONSTANT 301
+#define BOOLCONSTANT 302
+#define FIELD_SELECTION 303
+#define LEFT_OP 304
+#define RIGHT_OP 305
+#define INC_OP 306
+#define DEC_OP 307
+#define LE_OP 308
+#define GE_OP 309
+#define EQ_OP 310
+#define NE_OP 311
+#define AND_OP 312
+#define OR_OP 313
+#define XOR_OP 314
+#define MUL_ASSIGN 315
+#define DIV_ASSIGN 316
+#define ADD_ASSIGN 317
+#define MOD_ASSIGN 318
+#define LEFT_ASSIGN 319
+#define RIGHT_ASSIGN 320
+#define AND_ASSIGN 321
+#define XOR_ASSIGN 322
+#define OR_ASSIGN 323
+#define SUB_ASSIGN 324
+#define LEFT_PAREN 325
+#define RIGHT_PAREN 326
+#define LEFT_BRACKET 327
+#define RIGHT_BRACKET 328
+#define LEFT_BRACE 329
+#define RIGHT_BRACE 330
+#define DOT 331
+#define COMMA 332
+#define COLON 333
+#define EQUAL 334
+#define SEMICOLON 335
+#define BANG 336
+#define DASH 337
+#define TILDE 338
+#define PLUS 339
+#define STAR 340
+#define SLASH 341
+#define PERCENT 342
+#define LEFT_ANGLE 343
+#define RIGHT_ANGLE 344
+#define VERTICAL_BAR 345
+#define CARET 346
+#define AMPERSAND 347
+#define QUESTION 348
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+
+{
+    struct {
+        TSourceLoc line;
+        union {
+            TString *string;
+            float f;
+            int i;
+            bool b;
+        };
+        TSymbol* symbol;
+    } lex;
+    struct {
+        TSourceLoc line;
+        TOperator op;
+        union {
+            TIntermNode* intermNode;
+            TIntermNodePair nodePair;
+            TIntermTyped* intermTypedNode;
+            TIntermAggregate* intermAggregate;
+        };
+        union {
+            TPublicType type;
+            TPrecision precision;
+            TQualifier qualifier;
+            TFunction* function;
+            TParameter param;
+            TTypeLine typeLine;
+            TTypeList* typeList;
+        };
+    } interm;
+}
+/* Line 1489 of yacc.c.  */
+
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp b/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp
index db042dd..798a69a 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp
@@ -21,8 +21,8 @@
 //
 class TOutputTraverser : public TIntermTraverser {
 public:
-    TOutputTraverser(TInfoSink& i) : infoSink(i) { }
-    TInfoSink& infoSink;
+    TOutputTraverser(TInfoSinkBase& i) : sink(i) { }
+    TInfoSinkBase& sink;
 
 protected:
     void visitSymbol(TIntermSymbol*);
@@ -56,14 +56,14 @@
 // Helper functions for printing, not part of traversing.
 //
 
-void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
+void OutputTreeText(TInfoSinkBase& sink, TIntermNode* node, const int depth)
 {
     int i;
 
-    infoSink.debug.location(node->getLine());
+    sink.location(node->getLine());
 
     for (i = 0; i < depth; ++i)
-        infoSink.debug << "  ";
+        sink << "  ";
 }
 
 //
@@ -77,226 +77,226 @@
 
 void TOutputTraverser::visitSymbol(TIntermSymbol* node)
 {
-    OutputTreeText(infoSink, node, depth);
+    OutputTreeText(sink, node, depth);
 
-    infoSink.debug << "'" << node->getSymbol() << "' ";
-    infoSink.debug << "(" << node->getCompleteString() << ")\n";
+    sink << "'" << node->getSymbol() << "' ";
+    sink << "(" << node->getCompleteString() << ")\n";
 }
 
 bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node)
 {
-    TInfoSink& out = infoSink;
+    TInfoSinkBase& out = sink;
 
     OutputTreeText(out, node, depth);
 
     switch (node->getOp()) {
-        case EOpAssign:                   out.debug << "move second child to first child";           break;
-        case EOpInitialize:               out.debug << "initialize first child with second child";   break;
-        case EOpAddAssign:                out.debug << "add second child into first child";          break;
-        case EOpSubAssign:                out.debug << "subtract second child into first child";     break;
-        case EOpMulAssign:                out.debug << "multiply second child into first child";     break;
-        case EOpVectorTimesMatrixAssign:  out.debug << "matrix mult second child into first child";  break;
-        case EOpVectorTimesScalarAssign:  out.debug << "vector scale second child into first child"; break;
-        case EOpMatrixTimesScalarAssign:  out.debug << "matrix scale second child into first child"; break;
-        case EOpMatrixTimesMatrixAssign:  out.debug << "matrix mult second child into first child"; break;
-        case EOpDivAssign:                out.debug << "divide second child into first child";       break;
-        case EOpIndexDirect:   out.debug << "direct index";   break;
-        case EOpIndexIndirect: out.debug << "indirect index"; break;
-        case EOpIndexDirectStruct:   out.debug << "direct index for structure";   break;
-        case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
+        case EOpAssign:                   out << "move second child to first child";           break;
+        case EOpInitialize:               out << "initialize first child with second child";   break;
+        case EOpAddAssign:                out << "add second child into first child";          break;
+        case EOpSubAssign:                out << "subtract second child into first child";     break;
+        case EOpMulAssign:                out << "multiply second child into first child";     break;
+        case EOpVectorTimesMatrixAssign:  out << "matrix mult second child into first child";  break;
+        case EOpVectorTimesScalarAssign:  out << "vector scale second child into first child"; break;
+        case EOpMatrixTimesScalarAssign:  out << "matrix scale second child into first child"; break;
+        case EOpMatrixTimesMatrixAssign:  out << "matrix mult second child into first child"; break;
+        case EOpDivAssign:                out << "divide second child into first child";       break;
+        case EOpIndexDirect:   out << "direct index";   break;
+        case EOpIndexIndirect: out << "indirect index"; break;
+        case EOpIndexDirectStruct:   out << "direct index for structure";   break;
+        case EOpVectorSwizzle: out << "vector swizzle"; break;
 
-        case EOpAdd:    out.debug << "add";                     break;
-        case EOpSub:    out.debug << "subtract";                break;
-        case EOpMul:    out.debug << "component-wise multiply"; break;
-        case EOpDiv:    out.debug << "divide";                  break;
-        case EOpEqual:            out.debug << "Compare Equal";                 break;
-        case EOpNotEqual:         out.debug << "Compare Not Equal";             break;
-        case EOpLessThan:         out.debug << "Compare Less Than";             break;
-        case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
-        case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
-        case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
+        case EOpAdd:    out << "add";                     break;
+        case EOpSub:    out << "subtract";                break;
+        case EOpMul:    out << "component-wise multiply"; break;
+        case EOpDiv:    out << "divide";                  break;
+        case EOpEqual:            out << "Compare Equal";                 break;
+        case EOpNotEqual:         out << "Compare Not Equal";             break;
+        case EOpLessThan:         out << "Compare Less Than";             break;
+        case EOpGreaterThan:      out << "Compare Greater Than";          break;
+        case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
+        case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
 
-        case EOpVectorTimesScalar: out.debug << "vector-scale";          break;
-        case EOpVectorTimesMatrix: out.debug << "vector-times-matrix";   break;
-        case EOpMatrixTimesVector: out.debug << "matrix-times-vector";   break;
-        case EOpMatrixTimesScalar: out.debug << "matrix-scale";          break;
-        case EOpMatrixTimesMatrix: out.debug << "matrix-multiply";       break;
+        case EOpVectorTimesScalar: out << "vector-scale";          break;
+        case EOpVectorTimesMatrix: out << "vector-times-matrix";   break;
+        case EOpMatrixTimesVector: out << "matrix-times-vector";   break;
+        case EOpMatrixTimesScalar: out << "matrix-scale";          break;
+        case EOpMatrixTimesMatrix: out << "matrix-multiply";       break;
 
-        case EOpLogicalOr:  out.debug << "logical-or";   break;
-        case EOpLogicalXor: out.debug << "logical-xor"; break;
-        case EOpLogicalAnd: out.debug << "logical-and"; break;
-        default: out.debug << "<unknown op>";
+        case EOpLogicalOr:  out << "logical-or";   break;
+        case EOpLogicalXor: out << "logical-xor"; break;
+        case EOpLogicalAnd: out << "logical-and"; break;
+        default: out << "<unknown op>";
     }
 
-    out.debug << " (" << node->getCompleteString() << ")";
+    out << " (" << node->getCompleteString() << ")";
 
-    out.debug << "\n";
+    out << "\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
 {
-    TInfoSink& out = infoSink;
+    TInfoSinkBase& out = sink;
 
     OutputTreeText(out, node, depth);
 
     switch (node->getOp()) {
-        case EOpNegative:       out.debug << "Negate value";         break;
+        case EOpNegative:       out << "Negate value";         break;
         case EOpVectorLogicalNot:
-        case EOpLogicalNot:     out.debug << "Negate conditional";   break;
+        case EOpLogicalNot:     out << "Negate conditional";   break;
 
-        case EOpPostIncrement:  out.debug << "Post-Increment";       break;
-        case EOpPostDecrement:  out.debug << "Post-Decrement";       break;
-        case EOpPreIncrement:   out.debug << "Pre-Increment";        break;
-        case EOpPreDecrement:   out.debug << "Pre-Decrement";        break;
+        case EOpPostIncrement:  out << "Post-Increment";       break;
+        case EOpPostDecrement:  out << "Post-Decrement";       break;
+        case EOpPreIncrement:   out << "Pre-Increment";        break;
+        case EOpPreDecrement:   out << "Pre-Decrement";        break;
 
-        case EOpConvIntToBool:  out.debug << "Convert int to bool";  break;
-        case EOpConvFloatToBool:out.debug << "Convert float to bool";break;
-        case EOpConvBoolToFloat:out.debug << "Convert bool to float";break;
-        case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
-        case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
-        case EOpConvBoolToInt:  out.debug << "Convert bool to int";  break;
+        case EOpConvIntToBool:  out << "Convert int to bool";  break;
+        case EOpConvFloatToBool:out << "Convert float to bool";break;
+        case EOpConvBoolToFloat:out << "Convert bool to float";break;
+        case EOpConvIntToFloat: out << "Convert int to float"; break;
+        case EOpConvFloatToInt: out << "Convert float to int"; break;
+        case EOpConvBoolToInt:  out << "Convert bool to int";  break;
 
-        case EOpRadians:        out.debug << "radians";              break;
-        case EOpDegrees:        out.debug << "degrees";              break;
-        case EOpSin:            out.debug << "sine";                 break;
-        case EOpCos:            out.debug << "cosine";               break;
-        case EOpTan:            out.debug << "tangent";              break;
-        case EOpAsin:           out.debug << "arc sine";             break;
-        case EOpAcos:           out.debug << "arc cosine";           break;
-        case EOpAtan:           out.debug << "arc tangent";          break;
+        case EOpRadians:        out << "radians";              break;
+        case EOpDegrees:        out << "degrees";              break;
+        case EOpSin:            out << "sine";                 break;
+        case EOpCos:            out << "cosine";               break;
+        case EOpTan:            out << "tangent";              break;
+        case EOpAsin:           out << "arc sine";             break;
+        case EOpAcos:           out << "arc cosine";           break;
+        case EOpAtan:           out << "arc tangent";          break;
 
-        case EOpExp:            out.debug << "exp";                  break;
-        case EOpLog:            out.debug << "log";                  break;
-        case EOpExp2:           out.debug << "exp2";                 break;
-        case EOpLog2:           out.debug << "log2";                 break;
-        case EOpSqrt:           out.debug << "sqrt";                 break;
-        case EOpInverseSqrt:    out.debug << "inverse sqrt";         break;
+        case EOpExp:            out << "exp";                  break;
+        case EOpLog:            out << "log";                  break;
+        case EOpExp2:           out << "exp2";                 break;
+        case EOpLog2:           out << "log2";                 break;
+        case EOpSqrt:           out << "sqrt";                 break;
+        case EOpInverseSqrt:    out << "inverse sqrt";         break;
 
-        case EOpAbs:            out.debug << "Absolute value";       break;
-        case EOpSign:           out.debug << "Sign";                 break;
-        case EOpFloor:          out.debug << "Floor";                break;
-        case EOpCeil:           out.debug << "Ceiling";              break;
-        case EOpFract:          out.debug << "Fraction";             break;
+        case EOpAbs:            out << "Absolute value";       break;
+        case EOpSign:           out << "Sign";                 break;
+        case EOpFloor:          out << "Floor";                break;
+        case EOpCeil:           out << "Ceiling";              break;
+        case EOpFract:          out << "Fraction";             break;
 
-        case EOpLength:         out.debug << "length";               break;
-        case EOpNormalize:      out.debug << "normalize";            break;
-            //	case EOpDPdx:           out.debug << "dPdx";                 break;               
-            //	case EOpDPdy:           out.debug << "dPdy";                 break;   
-            //	case EOpFwidth:         out.debug << "fwidth";               break;                   
+        case EOpLength:         out << "length";               break;
+        case EOpNormalize:      out << "normalize";            break;
+            //	case EOpDPdx:           out << "dPdx";                 break;               
+            //	case EOpDPdy:           out << "dPdy";                 break;   
+            //	case EOpFwidth:         out << "fwidth";               break;                   
 
-        case EOpAny:            out.debug << "any";                  break;
-        case EOpAll:            out.debug << "all";                  break;
+        case EOpAny:            out << "any";                  break;
+        case EOpAll:            out << "all";                  break;
 
-        default: out.debug.message(EPrefixError, "Bad unary op");
+        default: out.message(EPrefixError, "Bad unary op");
     }
 
-    out.debug << " (" << node->getCompleteString() << ")";
+    out << " (" << node->getCompleteString() << ")";
 
-    out.debug << "\n";
+    out << "\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
 {
-    TInfoSink& out = infoSink;
+    TInfoSinkBase& out = sink;
 
     if (node->getOp() == EOpNull) {
-        out.debug.message(EPrefixError, "node is still EOpNull!");
+        out.message(EPrefixError, "node is still EOpNull!");
         return true;
     }
 
     OutputTreeText(out, node, depth);
 
     switch (node->getOp()) {
-        case EOpSequence:      out.debug << "Sequence\n"; return true;
-        case EOpComma:         out.debug << "Comma\n"; return true;
-        case EOpFunction:      out.debug << "Function Definition: " << node->getName(); break;
-        case EOpFunctionCall:  out.debug << "Function Call: " << node->getName(); break;
-        case EOpParameters:    out.debug << "Function Parameters: ";              break;
+        case EOpSequence:      out << "Sequence\n"; return true;
+        case EOpComma:         out << "Comma\n"; return true;
+        case EOpFunction:      out << "Function Definition: " << node->getName(); break;
+        case EOpFunctionCall:  out << "Function Call: " << node->getName(); break;
+        case EOpParameters:    out << "Function Parameters: ";              break;
 
-        case EOpConstructFloat: out.debug << "Construct float"; break;
-        case EOpConstructVec2:  out.debug << "Construct vec2";  break;
-        case EOpConstructVec3:  out.debug << "Construct vec3";  break;
-        case EOpConstructVec4:  out.debug << "Construct vec4";  break;
-        case EOpConstructBool:  out.debug << "Construct bool";  break;
-        case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
-        case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
-        case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
-        case EOpConstructInt:   out.debug << "Construct int";   break;
-        case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
-        case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
-        case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
-        case EOpConstructMat2:  out.debug << "Construct mat2";  break;
-        case EOpConstructMat3:  out.debug << "Construct mat3";  break;
-        case EOpConstructMat4:  out.debug << "Construct mat4";  break;
-        case EOpConstructStruct:  out.debug << "Construct structure";  break;
+        case EOpConstructFloat: out << "Construct float"; break;
+        case EOpConstructVec2:  out << "Construct vec2";  break;
+        case EOpConstructVec3:  out << "Construct vec3";  break;
+        case EOpConstructVec4:  out << "Construct vec4";  break;
+        case EOpConstructBool:  out << "Construct bool";  break;
+        case EOpConstructBVec2: out << "Construct bvec2"; break;
+        case EOpConstructBVec3: out << "Construct bvec3"; break;
+        case EOpConstructBVec4: out << "Construct bvec4"; break;
+        case EOpConstructInt:   out << "Construct int";   break;
+        case EOpConstructIVec2: out << "Construct ivec2"; break;
+        case EOpConstructIVec3: out << "Construct ivec3"; break;
+        case EOpConstructIVec4: out << "Construct ivec4"; break;
+        case EOpConstructMat2:  out << "Construct mat2";  break;
+        case EOpConstructMat3:  out << "Construct mat3";  break;
+        case EOpConstructMat4:  out << "Construct mat4";  break;
+        case EOpConstructStruct:  out << "Construct structure";  break;
 
-        case EOpLessThan:         out.debug << "Compare Less Than";             break;
-        case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
-        case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
-        case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
-        case EOpVectorEqual:      out.debug << "Equal";                         break;
-        case EOpVectorNotEqual:   out.debug << "NotEqual";                      break;
+        case EOpLessThan:         out << "Compare Less Than";             break;
+        case EOpGreaterThan:      out << "Compare Greater Than";          break;
+        case EOpLessThanEqual:    out << "Compare Less Than or Equal";    break;
+        case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
+        case EOpVectorEqual:      out << "Equal";                         break;
+        case EOpVectorNotEqual:   out << "NotEqual";                      break;
 
-        case EOpMod:           out.debug << "mod";         break;
-        case EOpPow:           out.debug << "pow";         break;
+        case EOpMod:           out << "mod";         break;
+        case EOpPow:           out << "pow";         break;
 
-        case EOpAtan:          out.debug << "arc tangent"; break;
+        case EOpAtan:          out << "arc tangent"; break;
 
-        case EOpMin:           out.debug << "min";         break;
-        case EOpMax:           out.debug << "max";         break;
-        case EOpClamp:         out.debug << "clamp";       break;
-        case EOpMix:           out.debug << "mix";         break;
-        case EOpStep:          out.debug << "step";        break;
-        case EOpSmoothStep:    out.debug << "smoothstep";  break;
+        case EOpMin:           out << "min";         break;
+        case EOpMax:           out << "max";         break;
+        case EOpClamp:         out << "clamp";       break;
+        case EOpMix:           out << "mix";         break;
+        case EOpStep:          out << "step";        break;
+        case EOpSmoothStep:    out << "smoothstep";  break;
 
-        case EOpDistance:      out.debug << "distance";                break;
-        case EOpDot:           out.debug << "dot-product";             break;
-        case EOpCross:         out.debug << "cross-product";           break;
-        case EOpFaceForward:   out.debug << "face-forward";            break;
-        case EOpReflect:       out.debug << "reflect";                 break;
-        case EOpRefract:       out.debug << "refract";                 break;
-        case EOpMul:           out.debug << "component-wise multiply"; break;
+        case EOpDistance:      out << "distance";                break;
+        case EOpDot:           out << "dot-product";             break;
+        case EOpCross:         out << "cross-product";           break;
+        case EOpFaceForward:   out << "face-forward";            break;
+        case EOpReflect:       out << "reflect";                 break;
+        case EOpRefract:       out << "refract";                 break;
+        case EOpMul:           out << "component-wise multiply"; break;
 
-        default: out.debug.message(EPrefixError, "Bad aggregation op");
+        default: out.message(EPrefixError, "Bad aggregation op");
     }
 
     if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
-        out.debug << " (" << node->getCompleteString() << ")";
+        out << " (" << node->getCompleteString() << ")";
 
-    out.debug << "\n";
+    out << "\n";
 
     return true;
 }
 
 bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
 {
-    TInfoSink& out = infoSink;
+    TInfoSinkBase& out = sink;
 
     OutputTreeText(out, node, depth);
 
-    out.debug << "Test condition and select";
-    out.debug << " (" << node->getCompleteString() << ")\n";
+    out << "Test condition and select";
+    out << " (" << node->getCompleteString() << ")\n";
 
     ++depth;
 
-    OutputTreeText(infoSink, node, depth);
-    out.debug << "Condition\n";
+    OutputTreeText(sink, node, depth);
+    out << "Condition\n";
     node->getCondition()->traverse(this);
 
-    OutputTreeText(infoSink, node, depth);
+    OutputTreeText(sink, node, depth);
     if (node->getTrueBlock()) {
-        out.debug << "true case\n";
+        out << "true case\n";
         node->getTrueBlock()->traverse(this);
     } else
-        out.debug << "true case is null\n";
+        out << "true case is null\n";
 
     if (node->getFalseBlock()) {
-        OutputTreeText(infoSink, node, depth);
-        out.debug << "false case\n";
+        OutputTreeText(sink, node, depth);
+        out << "false case\n";
         node->getFalseBlock()->traverse(this);
     }
 
@@ -307,7 +307,7 @@
 
 void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
 {
-    TInfoSink& out = infoSink;
+    TInfoSinkBase& out = sink;
 
     int size = node->getType().getObjectSize();
 
@@ -316,23 +316,23 @@
         switch (node->getUnionArrayPointer()[i].getType()) {
             case EbtBool:
                 if (node->getUnionArrayPointer()[i].getBConst())
-                    out.debug << "true";
+                    out << "true";
                 else
-                    out.debug << "false";
+                    out << "false";
 
-                out.debug << " (" << "const bool" << ")";
-                out.debug << "\n";
+                out << " (" << "const bool" << ")";
+                out << "\n";
                 break;
             case EbtFloat:
-                out.debug << node->getUnionArrayPointer()[i].getFConst();
-                out.debug << " (const float)\n";
+                out << node->getUnionArrayPointer()[i].getFConst();
+                out << " (const float)\n";
                 break;
             case EbtInt:
-                out.debug << node->getUnionArrayPointer()[i].getIConst();
-                out.debug << " (const int)\n";
+                out << node->getUnionArrayPointer()[i].getIConst();
+                out << " (const int)\n";
                 break;
             default:
-                out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
+                out.message(EPrefixInternalError, "Unknown constant", node->getLine());
                 break;
         }
     }
@@ -340,35 +340,35 @@
 
 bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
 {
-    TInfoSink& out = infoSink;
+    TInfoSinkBase& out = sink;
 
     OutputTreeText(out, node, depth);
 
-    out.debug << "Loop with condition ";
-    if (! node->testFirst())
-        out.debug << "not ";
-    out.debug << "tested first\n";
+    out << "Loop with condition ";
+    if (node->getType() == ELoopDoWhile)
+        out << "not ";
+    out << "tested first\n";
 
     ++depth;
 
-    OutputTreeText(infoSink, node, depth);
-    if (node->getTest()) {
-        out.debug << "Loop Condition\n";
-        node->getTest()->traverse(this);
+    OutputTreeText(sink, node, depth);
+    if (node->getCondition()) {
+        out << "Loop Condition\n";
+        node->getCondition()->traverse(this);
     } else
-        out.debug << "No loop condition\n";
+        out << "No loop condition\n";
 
-    OutputTreeText(infoSink, node, depth);
+    OutputTreeText(sink, node, depth);
     if (node->getBody()) {
-        out.debug << "Loop Body\n";
+        out << "Loop Body\n";
         node->getBody()->traverse(this);
     } else
-        out.debug << "No loop body\n";
+        out << "No loop body\n";
 
-    if (node->getTerminal()) {
-        OutputTreeText(infoSink, node, depth);
-        out.debug << "Loop Terminal Expression\n";
-        node->getTerminal()->traverse(this);
+    if (node->getExpression()) {
+        OutputTreeText(sink, node, depth);
+        out << "Loop Terminal Expression\n";
+        node->getExpression()->traverse(this);
     }
 
     --depth;
@@ -378,25 +378,25 @@
 
 bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch* node)
 {
-    TInfoSink& out = infoSink;
+    TInfoSinkBase& out = sink;
 
     OutputTreeText(out, node, depth);
 
     switch (node->getFlowOp()) {
-        case EOpKill:      out.debug << "Branch: Kill";           break;
-        case EOpBreak:     out.debug << "Branch: Break";          break;
-        case EOpContinue:  out.debug << "Branch: Continue";       break;
-        case EOpReturn:    out.debug << "Branch: Return";         break;
-        default:           out.debug << "Branch: Unknown Branch"; break;
+        case EOpKill:      out << "Branch: Kill";           break;
+        case EOpBreak:     out << "Branch: Break";          break;
+        case EOpContinue:  out << "Branch: Continue";       break;
+        case EOpReturn:    out << "Branch: Return";         break;
+        default:           out << "Branch: Unknown Branch"; break;
     }
 
     if (node->getExpression()) {
-        out.debug << " with expression\n";
+        out << " with expression\n";
         ++depth;
         node->getExpression()->traverse(this);
         --depth;
     } else
-        out.debug << "\n";
+        out << "\n";
 
     return false;
 }
@@ -411,7 +411,7 @@
     if (root == 0)
         return;
 
-    TOutputTraverser it(infoSink);
+    TOutputTraverser it(infoSink.info);
 
     root->traverse(&it);
 }
diff --git a/Source/ThirdParty/ANGLE/src/compiler/intermediate.h b/Source/ThirdParty/ANGLE/src/compiler/intermediate.h
index d262905..f9fa1de 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/intermediate.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/intermediate.h
@@ -129,9 +129,9 @@
     EOpReflect,
     EOpRefract,
 
-    //EOpDPdx,            // Fragment only, OES_standard_derivatives extension
-    //EOpDPdy,            // Fragment only, OES_standard_derivatives extension
-    //EOpFwidth,          // Fragment only, OES_standard_derivatives extension
+    EOpDFdx,            // Fragment only, OES_standard_derivatives extension
+    EOpDFdy,            // Fragment only, OES_standard_derivatives extension
+    EOpFwidth,          // Fragment only, OES_standard_derivatives extension
 
     EOpMatrixTimesMatrix,
 
@@ -184,6 +184,8 @@
     EOpDivAssign,
 };
 
+extern const char* getOperatorString(TOperator op);
+
 class TIntermTraverser;
 class TIntermAggregate;
 class TIntermBinary;
@@ -262,30 +264,38 @@
 //
 // Handle for, do-while, and while loops.
 //
+enum TLoopType {
+    ELoopFor,
+    ELoopWhile,
+    ELoopDoWhile,
+};
+
 class TIntermLoop : public TIntermNode {
 public:
-    TIntermLoop(TIntermNode *init, TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) : 
-            init(init),
-            body(aBody),
-            test(aTest),
-            terminal(aTerminal),
-            first(testFirst) { }
+    TIntermLoop(TLoopType aType,
+                TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
+                TIntermNode* aBody) :
+            type(aType),
+            init(aInit),
+            cond(aCond),
+            expr(aExpr),
+            body(aBody) { }
 
     virtual TIntermLoop* getAsLoopNode() { return this; }
     virtual void traverse(TIntermTraverser*);
 
-    TIntermNode *getInit() { return init; }
-    TIntermNode *getBody() { return body; }
-    TIntermTyped *getTest() { return test; }
-    TIntermTyped *getTerminal() { return terminal; }
-    bool testFirst() { return first; }
+    TLoopType getType() const { return type; }
+    TIntermNode* getInit() { return init; }
+    TIntermTyped* getCondition() { return cond; }
+    TIntermTyped* getExpression() { return expr; }
+    TIntermNode* getBody() { return body; }
 
 protected:
-    TIntermNode *init;
-    TIntermNode *body;       // code to loop over
-    TIntermTyped *test;      // exit condition associated with loop, could be 0 for 'for' loops
-    TIntermTyped *terminal;  // exists for for-loops
-    bool first;              // true for while and for, not for do-while
+    TLoopType type;
+    TIntermNode* init;  // for-loop initialization
+    TIntermTyped* cond; // loop exit condition
+    TIntermTyped* expr; // for-loop expression
+    TIntermNode* body;  // loop body
 };
 
 //
@@ -404,6 +414,7 @@
 
 typedef TVector<TIntermNode*> TIntermSequence;
 typedef TVector<int> TQualifierList;
+typedef TMap<TString, TString> TPragmaTable;
 //
 // Nodes that operate on an arbitrary sized set of children.
 //
@@ -417,12 +428,13 @@
     virtual void traverse(TIntermTraverser*);
 
     TIntermSequence& getSequence() { return sequence; }
+
     void setName(const TString& n) { name = n; }
     const TString& getName() const { return name; }
 
     void setUserDefined() { userDefined = true; }
     bool isUserDefined() { return userDefined; }
-    TQualifierList& getQualifier() { return qualifier; }
+
     void setOptimize(bool o) { optimize = o; }
     bool getOptimize() { return optimize; }
     void setDebug(bool d) { debug = d; }
@@ -434,9 +446,9 @@
     TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
     TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
     TIntermSequence sequence;
-    TQualifierList qualifier;
     TString name;
     bool userDefined; // used for user defined function names
+
     bool optimize;
     bool debug;
     TPragmaTable *pragmaTable;
diff --git a/Source/ThirdParty/ANGLE/src/compiler/localintermediate.h b/Source/ThirdParty/ANGLE/src/compiler/localintermediate.h
index 5fd4c69..56890bd 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/localintermediate.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/localintermediate.h
@@ -40,11 +40,11 @@
     TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, TSourceLoc);
     TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
     bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);        
-    TIntermNode* addLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
+    TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, TSourceLoc);
     TIntermBranch* addBranch(TOperator, TSourceLoc);
     TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
     TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
-    bool postProcess(TIntermNode*, EShLanguage);
+    bool postProcess(TIntermNode*);
 	void remove(TIntermNode*);
     void outputTree(TIntermNode*);
     
diff --git a/Source/ThirdParty/ANGLE/src/compiler/osinclude.h b/Source/ThirdParty/ANGLE/src/compiler/osinclude.h
index d887914..1af5064 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/osinclude.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/osinclude.h
@@ -8,8 +8,8 @@
 #define __OSINCLUDE_H
 
 //
-// This file contains contains the window's specific datatypes and
-// declares any windows specific functions.
+// This file contains contains os-specific datatypes and
+// declares any os-specific functions.
 //
 
 #if defined(_WIN32) || defined(_WIN64)
@@ -22,7 +22,9 @@
 #error Unsupported platform.
 #endif
 
-#if defined(ANGLE_OS_WIN)
+#if defined(ANGLE_USE_NSPR)
+#include "prthread.h"
+#elif defined(ANGLE_OS_WIN)
 #define STRICT
 #define VC_EXTRALEAN 1
 #include <windows.h>
@@ -30,20 +32,24 @@
 #include <pthread.h>
 #include <semaphore.h>
 #include <errno.h>
-#endif  // ANGLE_OS_WIN
+#endif  // ANGLE_USE_NSPR
+
 
 #include "compiler/debug.h"
 
 //
 // Thread Local Storage Operations
 //
-#if defined(ANGLE_OS_WIN)
+#if defined(ANGLE_USE_NSPR)
+typedef PRUintn OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX 0xFFFFFFFF
+#elif defined(ANGLE_OS_WIN)
 typedef DWORD OS_TLSIndex;
 #define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
 #elif defined(ANGLE_OS_POSIX)
 typedef unsigned int OS_TLSIndex;
 #define OS_INVALID_TLS_INDEX 0xFFFFFFFF
-#endif  // ANGLE_OS_WIN
+#endif  // ANGLE_USE_NSPR
 
 OS_TLSIndex OS_AllocTLSIndex();
 bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
@@ -51,8 +57,10 @@
 
 inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
 {
-    assert(nIndex != OS_INVALID_TLS_INDEX);
-#if defined(ANGLE_OS_WIN)
+    ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+#if defined(ANGLE_USE_NSPR)
+    return PR_GetThreadPrivate(nIndex);
+#elif defined(ANGLE_OS_WIN)
     return TlsGetValue(nIndex);
 #elif defined(ANGLE_OS_POSIX)
     return pthread_getspecific(nIndex);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ossource_nspr.cpp b/Source/ThirdParty/ANGLE/src/compiler/ossource_nspr.cpp
new file mode 100644
index 0000000..f63d81e
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/ossource_nspr.cpp
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// This file contains the nspr specific functions
+//
+#include "compiler/osinclude.h"
+
+//
+// Thread Local Storage Operations
+//
+OS_TLSIndex OS_AllocTLSIndex()
+{
+    PRUintn index;
+    PRStatus status = PR_NewThreadPrivateIndex(&index, NULL);
+
+    if (status) {
+        assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
+        return OS_INVALID_TLS_INDEX;
+    }
+
+    return index;
+}
+
+bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+{
+    if (nIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
+        return false;
+    }
+
+    return PR_SetThreadPrivate(nIndex, lpvValue) == 0;
+}
+
+bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
+{
+    // Can't delete TLS keys with nspr
+    return true;
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h
index 5bfa902..69e3425 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h
@@ -89,10 +89,10 @@
     // Globals used to communicate between PaParseStrings() and yy_input()and 
     // also across the files.(gen_glslang.cpp and scanner.c)
     //
-    int    PaWhichStr;            // which string we're parsing
-    int*   PaStrLen;              // array of lengths of the PaArgv strings
-    int    PaArgc;                // count of strings in the array
-    char** PaArgv;                // our array of strings to parse    
+    int PaWhichStr;             // which string we're parsing
+    const int* PaStrLen;        // array of lengths of the PaArgv strings
+    int PaArgc;                 // count of strings in the array
+    const char* const* PaArgv;  // our array of strings to parse    
     unsigned int tokensBeforeEOF : 1;
 };
 
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c
index f15c56d..204a213 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c
@@ -191,6 +191,9 @@
         if (token == '\\') {
             CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
             return token;
+        } else if (token <= 0) { // EOF or error
+            CPPErrorToInfoLog("unexpected end of input in #define preprocessor directive - expected a newline");
+            return 0;
         }
         RecordToken(mac.body, token, yylvalpp);
         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
@@ -267,9 +270,13 @@
 	
 	while (token > 0) {
         if (token != '#') {
-		    while (token != '\n')
+            while (token != '\n') {
                 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-            
+                if (token <= 0) { // EOF or error
+                    CPPErrorToInfoLog("unexpected end of input in #else preprocessor directive - expected a newline");
+                    return 0;
+                }
+            }
             token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
             continue;
         }
@@ -295,8 +302,13 @@
                 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                 if (token != '\n') {
                     CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
-                    while (token != '\n')
+                    while (token != '\n') {
                         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                        if (token <= 0) { // EOF or error
+                            CPPErrorToInfoLog("unexpected end of input following #else preprocessor directive - expected a newline");
+                            return 0;
+                        }
+                    }
                 } 
 				break;
 			} 
@@ -467,9 +479,14 @@
 	}
 	token = eval(token, MIN_PREC, &res, &err, yylvalpp);
     if (token != '\n') {
-        CPPWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline");
-        while (token != '\n')
+        CPPWarningToInfoLog("unexpected tokens following #if preprocessor directive - expected a newline");
+        while (token != '\n') {
             token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (token <= 0) { // EOF or error
+                CPPErrorToInfoLog("unexpected end of input in #if preprocessor directive - expected a newline");
+                return 0;
+            }
+        }
     } 
     if (!res && !err) {
         token = CPPelse(1, yylvalpp);
@@ -495,8 +512,13 @@
         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
         if (token != '\n') {
             CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
-            while (token != '\n')
+            while (token != '\n') {
                 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                if (token <= 0) { // EOF or error
+                    CPPErrorToInfoLog("unexpected end of input in #ifdef preprocessor directive - expected a newline");
+                    return 0;
+                }
+            }
         }
         if (((s && !s->details.mac.undef) ? 1 : 0) != defined)
             token = CPPelse(1, yylvalpp);
@@ -544,7 +566,10 @@
     const char *message;
 	
     while (token != '\n') {
-		if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
+        if (token <= 0){
+            CPPErrorToInfoLog("unexpected end of input in #error preprocessor directive - expected a newline");
+            return 0;
+        }else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
             StoreStr(yylvalpp->symbol_name);
 		}else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
 			StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
@@ -670,7 +695,7 @@
 {
 
     int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-    char extensionName[80];
+    char extensionName[MAX_SYMBOL_NAME_LEN + 1];
 
     if(token=='\n'){
 		DecLineNumber();
@@ -682,7 +707,8 @@
     if (token != CPP_IDENTIFIER)
         CPPErrorToInfoLog("#extension");
     
-    strcpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
+    strncpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident), MAX_SYMBOL_NAME_LEN);
+    extensionName[MAX_SYMBOL_NAME_LEN] = '\0';
 	    
     token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
     if (token != ':') {
@@ -726,8 +752,13 @@
                  token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                  if (token != '\n') {
                      CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
-                     while (token != '\n')
+                     while (token != '\n') {
                          token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                         if (token <= 0) { // EOF or error
+                             CPPErrorToInfoLog("unexpected end of input in #ifdef preprocessor directive - expected a newline");
+                             return 0;
+                         }
+                     }
                  }
 			     token = CPPelse(0, yylvalpp);
              }else{
@@ -743,8 +774,14 @@
             } 
             // this token is really a dont care, but we still need to eat the tokens
             token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); 
-            while (token != '\n')
+            while (token != '\n') {
                 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                if (token <= 0) { // EOF or error
+                    CPPErrorToInfoLog("unexpect tokens following #elif preprocessor directive - expected a newline");
+                    cpp->CompileError = 1;
+                    break;
+                }
+            }
 		    token = CPPelse(0, yylvalpp);
         } else if (yylvalpp->sc_ident == endifAtom) {
 		     --cpp->elsetracker;
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h
index 0602c91..88d196f 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h
@@ -42,10 +42,10 @@
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 \****************************************************************************/
 
-# include "compiler/preprocessor/slglobals.h"
+#include "compiler/preprocessor/slglobals.h"
 extern CPPStruct *cpp;
 int InitCPPStruct(void);
 int InitScanner(CPPStruct *cpp);
 int InitAtomTable(AtomTable *atable, int htsize);
-int ScanFromString(char *s);
+int ScanFromString(const char *s);
 char* GetStringOfAtom(AtomTable *atable, int atom);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c
index c77d271..f4bfef9 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c
@@ -45,6 +45,7 @@
 // scanner.c
 //
 
+#include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -52,13 +53,13 @@
 
 #if 0
     #include <ieeefp.h>
-    #else
+#else
     #define isinff(x) (((*(int *)&(x) & 0x7f800000L)==0x7f800000L) && \
                        ((*(int *)&(x) & 0x007fffffL)==0000000000L))
 #endif
 
 #include "compiler/preprocessor/slglobals.h"
-
+#include "compiler/util.h"
 
 typedef struct StringInputSrc {
     InputSrc base;
@@ -133,49 +134,49 @@
  */
 static int str_getch(StringInputSrc *in)
 {
-	for(;;){
-	   if (*in->p){
-	      if (*in->p == '\n') {
+    for(;;){
+       if (*in->p){
+          if (*in->p == '\n') {
              in->base.line++;
              IncLineNumber();
           }
           return *in->p++;
-	   }
-	   if(++(cpp->PaWhichStr) < cpp->PaArgc){
-		  free(in);
-		  SetStringNumber(cpp->PaWhichStr);
-    	  SetLineNumber(1);
-		  ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
-		  in=(StringInputSrc*)cpp->currentInput;
-	      continue;             
-	   }
-	   else{
-	      cpp->currentInput = in->base.prev;
-	      cpp->PaWhichStr=0;
+       }
+       if(++(cpp->PaWhichStr) < cpp->PaArgc){
+          free(in);
+          SetStringNumber(cpp->PaWhichStr);
+          SetLineNumber(1);
+          ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
+          in=(StringInputSrc*)cpp->currentInput;
+          continue;             
+       }
+       else{
+          cpp->currentInput = in->base.prev;
+          cpp->PaWhichStr=0;
           free(in);
           return EOF;
        }  
-	}
+    }
 } // str_getch
 
 static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
     if (in->p[-1] == ch)in->p--;
-	else {
-		*(in->p)='\0'; //this would take care of shifting to the previous string.
-	    cpp->PaWhichStr--;
-	}  
-	if (ch == '\n') {
+    else {
+        *(in->p)='\0'; //this would take care of shifting to the previous string.
+        cpp->PaWhichStr--;
+    }  
+    if (ch == '\n') {
         in->base.line--;
         DecLineNumber();
     }
 } // str_ungetch
 
-int ScanFromString(char *s)
+int ScanFromString(const char *s)
 {
     
-	StringInputSrc *in = malloc(sizeof(StringInputSrc));
+    StringInputSrc *in = malloc(sizeof(StringInputSrc));
     memset(in, 0, sizeof(StringInputSrc));
-	in->p = s;
+    in->p = s;
     in->base.line = 1;
     in->base.scan = byte_scan;
     in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
@@ -190,119 +191,63 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////// Floating point constants: /////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////
-/*
- * lBuildFloatValue() - Quick and dirty conversion to floating point.  Since all
- *         we need is single precision this should be quite precise.
- */
 
-static float lBuildFloatValue(const char *str, int len, int exp)
-{
-    double val, expval, ten;
-    int ii, llen, absexp;
-    float rv;
-
-    val = 0.0;
-    llen = len;
-    for (ii = 0; ii < len; ii++)
-        val = val*10.0 + (str[ii] - '0');
-    if (exp != 0) {
-        absexp = exp > 0 ? exp : -exp;
-        expval = 1.0f;
-        ten = 10.0;
-        while (absexp) {
-            if (absexp & 1)
-                expval *= ten;
-            ten *= ten;
-            absexp >>= 1;
-        }
-        if (exp >= 0) {
-            val *= expval;
-        } else {
-            val /= expval;
-        }
-    }
-    rv = (float)val;
-    if (isinff(rv)) {
-		CPPErrorToInfoLog(" ERROR___FP_CONST_OVERFLOW");
-    }
-    return rv;
-} // lBuildFloatValue
-
+#define APPEND_CHAR_S(ch, str, len, max_len) \
+      if (len < max_len) { \
+          str[len++] = ch; \
+      } else if (!alreadyComplained) { \
+          CPPErrorToInfoLog("BUFFER OVERFLOW"); \
+          alreadyComplained = 1; \
+      }
 
 /*
  * lFloatConst() - Scan a floating point constant.  Assumes that the scanner
  *         has seen at least one digit, followed by either a decimal '.' or the
  *         letter 'e'.
+ * ch - '.' or 'e'
+ * len - length of string already copied into yylvalpp->symbol_name.
  */
 
-static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
+static int lFloatConst(int ch, int len, yystypepp * yylvalpp)
 {
-    int HasDecimal, declen, exp, ExpSign;
-    int str_len;
-    float lval;
-    
-    HasDecimal = 0;
-    declen = 0;
-    exp = 0;
-	
-    str_len=len;
+    int alreadyComplained = 0;
+    assert((ch == '.') || (ch == 'e') || (ch == 'E'));
+
     if (ch == '.') {
-		str[len++]=ch;
-        HasDecimal = 1;
-        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-        while (ch >= '0' && ch <= '9') {
-            if (len < MAX_SYMBOL_NAME_LEN) {
-                declen++;
-                if (len > 0 || ch != '0') {
-                    str[len] = ch;
-                    len++;str_len++;
-                }
-                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-            } else {
-                CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
-                len = 1,str_len=1;
-            }
-        }
+        do {
+            APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+        } while (ch >= '0' && ch <= '9');
     }
 
     // Exponent:
-
     if (ch == 'e' || ch == 'E') {
-        ExpSign = 1;
-		str[len++]=ch;
+        APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
         ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
         if (ch == '+') {
-            str[len++]=ch;  
-			ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
         } else if (ch == '-') {
-            ExpSign = -1;
-			str[len++]=ch;
+            APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
             ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
         }
         if (ch >= '0' && ch <= '9') {
             while (ch >= '0' && ch <= '9') {
-                exp = exp*10 + ch - '0';
-				str[len++]=ch;
+                APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
                 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             }
         } else {
-            CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
+            CPPErrorToInfoLog("EXPONENT INVALID");
         }
-        exp *= ExpSign;
     }
-      
-    if (len == 0) {
-        lval = 0.0f;
-		strcpy(str,"0.0");
-    } else {
-        str[len]='\0';      
-        lval = lBuildFloatValue(str, str_len, exp - declen);
+    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+
+    assert(len <= MAX_SYMBOL_NAME_LEN);
+    yylvalpp->symbol_name[len] = '\0';
+    yylvalpp->sc_fval = (float) atof_dot(yylvalpp->symbol_name);
+    if (isinff(yylvalpp->sc_fval)) {
+        CPPErrorToInfoLog("FLOAT CONSTANT OVERFLOW");
     }
-    // Suffix:
-    
-    yylvalpp->sc_fval = lval;
-    strcpy(yylvalpp->symbol_name,str);
-    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);            
     return CPP_FLOATCONSTANT;
 } // lFloatConst
 
@@ -312,29 +257,29 @@
     
 static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
 {
-    char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
     char string_val[MAX_STRING_LEN + 1];
-    int AlreadyComplained;
+    int alreadyComplained = 0;
     int len, ch, ii, ival = 0;
 
     for (;;) {
         yylvalpp->sc_int = 0;
         ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-		
+ 
         while (ch == ' ' || ch == '\t' || ch == '\r') {
             yylvalpp->sc_int = 1;
             ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
         }
-		
+        
         cpp->ltokenLoc.file = cpp->currentInput->name;
         cpp->ltokenLoc.line = cpp->currentInput->line;
+        alreadyComplained = 0;
         len = 0;
         switch (ch) {
         default:
-			return ch; // Single character token
+            return ch; // Single character token
         case EOF:
             return -1;
-		case 'A': case 'B': case 'C': case 'D': case 'E':
+        case 'A': case 'B': case 'C': case 'D': case 'E':
         case 'F': case 'G': case 'H': case 'I': case 'J':
         case 'K': case 'L': case 'M': case 'N': case 'O':
         case 'P': case 'Q': case 'R': case 'S': case 'T':
@@ -347,39 +292,32 @@
         case 'u': case 'v': case 'w': case 'x': case 'y':
         case 'z':            
             do {
-                if (len < MAX_SYMBOL_NAME_LEN) {
-                    symbol_name[len] = ch;
-                    len++;
-                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);					
-                } else {
-                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-                }
+                APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             } while ((ch >= 'a' && ch <= 'z') ||
                      (ch >= 'A' && ch <= 'Z') ||
                      (ch >= '0' && ch <= '9') ||
                      ch == '_');
-            if (len >= MAX_SYMBOL_NAME_LEN)
-                len = MAX_SYMBOL_NAME_LEN - 1;
-            symbol_name[len] = '\0';
+            assert(len <= MAX_SYMBOL_NAME_LEN);
+            yylvalpp->symbol_name[len] = '\0';
             cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
-            yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
+            yylvalpp->sc_ident = LookUpAddString(atable, yylvalpp->symbol_name);
             return CPP_IDENTIFIER;
             break;
         case '0':
-            yylvalpp->symbol_name[len++] = ch;
+            APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
             ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-            if (ch == 'x' || ch == 'X') {
-				yylvalpp->symbol_name[len++] = ch;
+            if (ch == 'x' || ch == 'X') {  // hexadecimal integer constants
+                APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
                 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                 if ((ch >= '0' && ch <= '9') ||
                     (ch >= 'A' && ch <= 'F') ||
                     (ch >= 'a' && ch <= 'f'))
                 {
-                    AlreadyComplained = 0;
                     ival = 0;
                     do {
-						yylvalpp->symbol_name[len++] = ch;
-                        if (ival <= 0x0fffffff) {
+                        if ((ival <= 0x0fffffff) && (len < MAX_SYMBOL_NAME_LEN)) {
+                            yylvalpp->symbol_name[len++] = ch;
                             if (ch >= '0' && ch <= '9') {
                                 ii = ch - '0';
                             } else if (ch >= 'A' && ch <= 'F') {
@@ -388,74 +326,67 @@
                                 ii = ch - 'a' + 10;
                             }
                             ival = (ival << 4) | ii;
-                        } else {
-                            if (!AlreadyComplained)
-                                CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
-                            AlreadyComplained = 1;
+                        } else if (!alreadyComplained) {
+                            CPPErrorToInfoLog("HEX CONSTANT OVERFLOW");
+                            alreadyComplained = 1;
                         }
                         ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                     } while ((ch >= '0' && ch <= '9') ||
                              (ch >= 'A' && ch <= 'F') ||
                              (ch >= 'a' && ch <= 'f'));
                 } else {
-                    CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT");
+                    CPPErrorToInfoLog("HEX CONSTANT INVALID");
                 }
+                assert(len <= MAX_SYMBOL_NAME_LEN);
                 yylvalpp->symbol_name[len] = '\0';
-				cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
-				yylvalpp->sc_int = ival;
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                yylvalpp->sc_int = ival;
                 return CPP_INTCONSTANT;
             } else if (ch >= '0' && ch <= '7') { // octal integer constants
-                AlreadyComplained = 0;
                 ival = 0;
                 do {
-                    yylvalpp->symbol_name[len++] = ch;
-                    if (ival <= 0x1fffffff) {
+                    if ((ival <= 0x1fffffff) && (len < MAX_SYMBOL_NAME_LEN)) {
+                        yylvalpp->symbol_name[len++] = ch;
                         ii = ch - '0';
                         ival = (ival << 3) | ii;
-                    } else {
-                        if (!AlreadyComplained)
-                           CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
-                        AlreadyComplained = 1;
+                    } else if (!alreadyComplained) {
+                        CPPErrorToInfoLog("OCT CONSTANT OVERFLOW");
+                        alreadyComplained = 1;
                     }
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                 } while (ch >= '0' && ch <= '7');
                 if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') 
-                     return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
+                     return lFloatConst(ch, len, yylvalpp);
+                assert(len <= MAX_SYMBOL_NAME_LEN);
                 yylvalpp->symbol_name[len] = '\0';
-				cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
-				yylvalpp->sc_int = ival;
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                yylvalpp->sc_int = ival;
                 return CPP_INTCONSTANT;
             } else {
-				cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
-				ch = '0';
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                ch = '0';
             }
             // Fall through...
         case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
             do {
-                if (len < MAX_SYMBOL_NAME_LEN) {
-                    if (len > 0 || ch != '0') {
-                        yylvalpp->symbol_name[len] = ch;
-                   len++;
-                    }
-                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-                }
+                APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             } while (ch >= '0' && ch <= '9');
             if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
-                return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
+                return lFloatConst(ch, len, yylvalpp);
             } else {
+                assert(len <= MAX_SYMBOL_NAME_LEN);
                 yylvalpp->symbol_name[len] = '\0';
-				cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
                 ival = 0;
-                AlreadyComplained = 0;
                 for (ii = 0; ii < len; ii++) {
                     ch = yylvalpp->symbol_name[ii] - '0';
-                    if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
-                        if (!AlreadyComplained)
-                           CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
-                        AlreadyComplained = 1;
-                    }
                     ival = ival*10 + ch;
+                    if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
+                        CPPErrorToInfoLog("INTEGER CONSTANT OVERFLOW");
+                        break;
+                    }
                 }
                 yylvalpp->sc_int = ival;
                 if(ival==0)
@@ -608,7 +539,7 @@
             ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             if (ch >= '0' && ch <= '9') {
                 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
-                return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
+                return lFloatConst('.', 0, yylvalpp);
             } else {
                 if (ch == '.') {
                     return -1; // Special EOF hack
@@ -633,14 +564,14 @@
                     while (ch != '*') {
                         if (ch == '\n') nlcount++;
                         if (ch == EOF) {
-                            CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
+                            CPPErrorToInfoLog("EOF IN COMMENT");
                             return -1;
                         }
                         ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                     }
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                     if (ch == EOF) {
-                        CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
+                        CPPErrorToInfoLog("EOF IN COMMENT");
                         return -1;
                     }
                 } while (ch != '/');
@@ -662,41 +593,40 @@
                     CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
                     return -1;
                 }
-                if (len < MAX_STRING_LEN) {
-                    string_val[len] = ch;
-                    len++;
-                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-                }
+                APPEND_CHAR_S(ch, string_val, len, MAX_STRING_LEN);
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             };
+            assert(len <= MAX_STRING_LEN);
             string_val[len] = '\0';
             if (ch == '"') {
                 yylvalpp->sc_ident = LookUpAddString(atable, string_val);
                 return CPP_STRCONSTANT;
             } else {
-                CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING");
+                CPPErrorToInfoLog("EOL IN STRING");
                 return ERROR_SY;
             }
+            break;
         }
     }
 } // byte_scan
 
 int yylex_CPP(char* buf, int maxSize)
 {    
-	yystypepp yylvalpp;
+    yystypepp yylvalpp;
     int token = '\n';   
 
     for(;;) {
 
         char* tokenString = 0;
         token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
-		if(check_EOF(token))
-		    return 0;
+        if(check_EOF(token))
+            return 0;
         if (token == '#') {
             if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
-			    token = readCPPline(&yylvalpp);
+                token = readCPPline(&yylvalpp);
                 if(check_EOF(token))
                     return 0;
-			    continue;
+                continue;
             } else {
                 CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line");
                 return 0;
@@ -708,30 +638,28 @@
             cpp->pastFirstStatement = 1;
             continue;
         }
-        
+
         if (token == '\n')
             continue;
-          
-        if (token == CPP_IDENTIFIER) {                
-            cpp->pastFirstStatement = 1;
+        cpp->pastFirstStatement = 1;
+
+        if (token == CPP_IDENTIFIER) {
             tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
-        } else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){             
-            cpp->pastFirstStatement = 1;            
+        } else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
             tokenString = yylvalpp.symbol_name;
-		} else {            
-            cpp->pastFirstStatement = 1;            
+        } else {
             tokenString = GetStringOfAtom(atable,token);
-	    }
+        }
 
         if (tokenString) {
-            if ((signed)strlen(tokenString) >= maxSize) {
-                cpp->tokensBeforeEOF = 1;
-                return maxSize;               
-            } else  if (strlen(tokenString) > 0) {
-			    strcpy(buf, tokenString);
-                cpp->tokensBeforeEOF = 1;
-                return (int)strlen(tokenString);
-            }  
+            int len = strlen(tokenString);
+            cpp->tokensBeforeEOF = 1;
+            if (len >= maxSize) {
+                return maxSize;
+            } else  if (len > 0) {
+                strcpy(buf, tokenString);
+                return len;
+            }
 
             return 0;
         }
@@ -745,7 +673,7 @@
 {
    if(token==-1){
        if(cpp->ifdepth >0){
-		CPPErrorToInfoLog("#endif missing!! Compilation stopped");
+        CPPErrorToInfoLog("#endif missing!! Compilation stopped");
         cpp->CompileError=1;
        }
       return 1;
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h
index 571fe57..0fee20d 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h
@@ -48,8 +48,9 @@
 #if !defined(__SCANNER_H)
 #define __SCANNER_H 1
 
-#define MAX_SYMBOL_NAME_LEN 128
-#define MAX_STRING_LEN 512
+// These lengths do not include the NULL terminator.
+#define MAX_SYMBOL_NAME_LEN 127
+#define MAX_STRING_LEN 511
 
 #include "compiler/preprocessor/parser.h"
 
@@ -59,8 +60,6 @@
     unsigned short file, line;
 } SourceLoc;
 
-int yyparse (void);
-
 int yylex_CPP(char* buf, int maxSize);
 
 typedef struct InputSrc {
@@ -73,7 +72,7 @@
 } InputSrc;
 
 int InitScanner(CPPStruct *cpp);   // Intialise the cpp scanner. 
-int ScanFromString(char *);      // Start scanning the input from the string mentioned.
+int ScanFromString(const char *);      // Start scanning the input from the string mentioned.
 int check_EOF(int);              // check if we hit a EOF abruptly 
 void CPPErrorToInfoLog(char *);   // sticking the msg,line into the Shader's.Info.log
 void SetLineNumber(int);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c
index 057cce8..aa83d2f 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c
@@ -52,6 +52,7 @@
 
 #include "compiler/debug.h"
 #include "compiler/preprocessor/slglobals.h"
+#include "compiler/util.h"
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
@@ -224,8 +225,7 @@
     case CPP_INTCONSTANT:
          str=yylvalpp->symbol_name;
          while (*str){
-            lAddByte(pTok,(unsigned char) *str);
-            *str++;
+            lAddByte(pTok, (unsigned char) *str++);
          }
          lAddByte(pTok, 0);
          break;
@@ -276,8 +276,7 @@
                      ch == '_')
             {
                 if (len < MAX_SYMBOL_NAME_LEN) {
-                    symbol_name[len] = ch;
-                    len++;
+                    symbol_name[len++] = ch;
                     ch = lReadByte(pTok);
                 }
             }
@@ -291,7 +290,7 @@
             while ((ch = lReadByte(pTok)) != 0)
                 if (len < MAX_STRING_LEN)
                     string_val[len++] = ch;
-            string_val[len] = 0;
+            string_val[len] = '\0';
             yylvalpp->sc_ident = LookUpAddString(atable, string_val);
             break;
         case CPP_FLOATCONSTANT:
@@ -300,15 +299,14 @@
             while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
             {
                 if (len < MAX_SYMBOL_NAME_LEN) {
-                    symbol_name[len] = ch;
-                    len++;
+                    symbol_name[len++] = ch;
                     ch = lReadByte(pTok);
                 }
             }
             symbol_name[len] = '\0';
             assert(ch == '\0');
             strcpy(yylvalpp->symbol_name,symbol_name);
-            yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
+            yylvalpp->sc_fval=(float)atof_dot(yylvalpp->symbol_name);
             break;
         case CPP_INTCONSTANT:
             len = 0;
@@ -316,8 +314,7 @@
             while ((ch >= '0' && ch <= '9'))
             {
                 if (len < MAX_SYMBOL_NAME_LEN) {
-                    symbol_name[len] = ch;
-                    len++;
+                    symbol_name[len++] = ch;
                     ch = lReadByte(pTok);
                 }
             }
diff --git a/Source/ThirdParty/ANGLE/src/compiler/unistd.h b/Source/ThirdParty/ANGLE/src/compiler/unistd.h
deleted file mode 100644
index c7c9147..0000000
--- a/Source/ThirdParty/ANGLE/src/compiler/unistd.h
+++ /dev/null
@@ -1 +0,0 @@
-// This is a NULL file and is meant to be empty
diff --git a/Source/ThirdParty/ANGLE/src/compiler/util.cpp b/Source/ThirdParty/ANGLE/src/compiler/util.cpp
new file mode 100644
index 0000000..b46e4d0
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/util.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#ifdef _MSC_VER
+    #include <locale.h>
+#else
+    #include <sstream>
+#endif
+
+double atof_dot(const char *str)
+{
+#ifdef _MSC_VER
+    _locale_t l = _create_locale(LC_NUMERIC, "C");
+    double result = _atof_l(str, l);
+    _free_locale(l);
+    return result;
+#else
+    double result;
+    std::istringstream s(str);
+    std::locale l("C");
+    s.imbue(l);
+    s >> result;
+    return result;
+#endif
+}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/util.h b/Source/ThirdParty/ANGLE/src/compiler/util.h
new file mode 100644
index 0000000..35288b7
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/util.h
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_UTIL_H
+#define COMPILER_UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// atof_dot is like atof but forcing C locale, i.e. forcing '.' as decimal point.
+double atof_dot(const char *str);
+
+#ifdef __cplusplus
+} // end extern "C"
+#endif
+
+#endif // COMPILER_UTIL_H
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp
index 21d4661..284f61d 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp
@@ -94,13 +94,6 @@
         mBlueSize = 5;
         mAlphaSize = 0;
         break;
-      case D3DFMT_X1R5G5B5:
-        mBufferSize = 16;
-        mRedSize = 5;
-        mGreenSize = 5;
-        mBlueSize = 5;
-        mAlphaSize = 0;
-        break;
       case D3DFMT_X8R8G8B8:
         mBufferSize = 32;
         mRedSize = 8;
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp
index e2802da..6f1a335 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp
@@ -17,7 +17,8 @@
 
 #include "libEGL/main.h"
 
-#define REF_RAST 0   // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
+#define REF_RAST 0        // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
+#define ENABLE_D3D9EX 1   // Enables use of the IDirect3D9Ex interface, when available
 
 namespace egl
 {
@@ -40,7 +41,6 @@
 
     mMinSwapInterval = 1;
     mMaxSwapInterval = 1;
-    setSwapInterval(1);
 }
 
 Display::~Display()
@@ -77,7 +77,7 @@
     // Use Direct3D9Ex if available. Among other things, this version is less
     // inclined to report a lost context, for example when the user switches
     // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
-    if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
+    if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
     {
         ASSERT(mD3d9ex);
         mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
@@ -95,11 +95,26 @@
         //  UNIMPLEMENTED();   // FIXME: Determine which adapter index the device context corresponds to
         }
 
-        HRESULT result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
-
-        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+        HRESULT result;
+        
+        // Give up on getting device caps after about one second.
+        for (int i = 0; i < 10; ++i)
         {
-            return error(EGL_BAD_ALLOC, false);
+            result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
+            
+            if (SUCCEEDED(result))
+            {
+                break;
+            }
+            else if (result == D3DERR_NOTAVAILABLE)
+            {
+                Sleep(100);   // Give the driver some time to initialize/recover
+            }
+            else if (FAILED(result))   // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from
+            {
+                terminate();
+                return error(EGL_BAD_ALLOC, false);
+            }
         }
 
         if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
@@ -108,6 +123,14 @@
             return error(EGL_NOT_INITIALIZED, false);
         }
 
+        // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported.
+        // This is required by Texture2D::convertToRenderTarget.
+        if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0)
+        {
+            terminate();
+            return error(EGL_NOT_INITIALIZED, false);
+        }
+
         mMinSwapInterval = 4;
         mMaxSwapInterval = 0;
 
@@ -123,7 +146,7 @@
         //  D3DFMT_A2R10G10B10,   // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
             D3DFMT_A8R8G8B8,
             D3DFMT_R5G6B5,
-            D3DFMT_X1R5G5B5,
+        //  D3DFMT_X1R5G5B5,      // Has no compatible OpenGL ES renderbuffer format
             D3DFMT_X8R8G8B8
         };
 
@@ -183,13 +206,6 @@
 
             mConfigSet.mSet.insert(configuration);
         }
-
-        if (!createDevice())
-        {
-            terminate();
-
-            return false;
-        }
     }
 
     if (!isInitialized())
@@ -199,23 +215,34 @@
         return false;
     }
 
+    static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
+    static const TCHAR className[] = TEXT("STATIC");
+
+    mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
+
     return true;
 }
 
 void Display::terminate()
 {
-    for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+    while (!mSurfaceSet.empty())
     {
-        delete *surface;
+        destroySurface(*mSurfaceSet.begin());
     }
 
-    for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
+    while (!mContextSet.empty())
     {
-        glDestroyContext(*context);
+        destroyContext(*mContextSet.begin());
     }
 
     if (mDevice)
     {
+        // If the device is lost, reset it first to prevent leaving the driver in an unstable state
+        if (FAILED(mDevice->TestCooperativeLevel()))
+        {
+            resetDevice();
+        }
+
         mDevice->Release();
         mDevice = NULL;
     }
@@ -314,33 +341,12 @@
 
 bool Display::createDevice()
 {
-    static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
-    static const TCHAR className[] = TEXT("STATIC");
-
-    mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
-
-    D3DPRESENT_PARAMETERS presentParameters = {0};
-
-    // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
-    presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
-    presentParameters.BackBufferCount = 1;
-    presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
-    presentParameters.BackBufferWidth = 1;
-    presentParameters.BackBufferHeight = 1;
-    presentParameters.EnableAutoDepthStencil = FALSE;
-    presentParameters.Flags = 0;
-    presentParameters.hDeviceWindow = mDeviceWindow;
-    presentParameters.MultiSampleQuality = 0;
-    presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
-    presentParameters.PresentationInterval = convertInterval(mMinSwapInterval);
-    presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
-    presentParameters.Windowed = TRUE;
-
+    D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
     DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
 
     HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
 
-    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
     {
         return error(EGL_BAD_ALLOC, false);
     }
@@ -349,14 +355,13 @@
     {
         result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
 
-        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+        if (FAILED(result))
         {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
             return error(EGL_BAD_ALLOC, false);
         }
     }
 
-    ASSERT(SUCCEEDED(result));
-
     // Permanent non-default states
     mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
 
@@ -365,6 +370,29 @@
     return true;
 }
 
+bool Display::resetDevice()
+{
+    D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+    HRESULT result;
+    
+    do
+    {
+        Sleep(0);   // Give the graphics driver some CPU time
+
+        result = mDevice->Reset(&presentParameters);
+    }
+    while (result == D3DERR_DEVICELOST);
+
+    if (FAILED(result))
+    {
+        return error(EGL_BAD_ALLOC, false);
+    }
+
+    ASSERT(SUCCEEDED(result));
+
+    return true;
+}
+
 Surface *Display::createWindowSurface(HWND window, EGLConfig config)
 {
     const Config *configuration = mConfigSet.get(config);
@@ -377,6 +405,27 @@
 
 EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
 {
+    if (!mDevice)
+    {
+        if (!createDevice())
+        {
+            return NULL;
+        }
+    }
+    else if (FAILED(mDevice->TestCooperativeLevel()))   // Lost device
+    {
+        if (!resetDevice())
+        {
+            return NULL;
+        }
+
+        // Restore any surfaces that may have been lost
+        for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+        {
+            (*surface)->resetSwapChain();
+        }
+    }
+
     const egl::Config *config = mConfigSet.get(configHandle);
 
     gl::Context *context = glCreateContext(config, shareContext);
@@ -395,6 +444,14 @@
 {
     glDestroyContext(context);
     mContextSet.erase(context);
+
+    if (mContextSet.empty() && mDevice && FAILED(mDevice->TestCooperativeLevel()))   // Last context of a lost device
+    {
+        for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+        {
+            (*surface)->release();
+        }	
+    }
 }
 
 bool Display::isInitialized()
@@ -430,37 +487,26 @@
     return false;
 }
 
-void Display::setSwapInterval(GLint interval)
+EGLint Display::getMinSwapInterval()
 {
-    mSwapInterval = interval;
-    mSwapInterval = std::max(mSwapInterval, mMinSwapInterval);
-    mSwapInterval = std::min(mSwapInterval, mMaxSwapInterval);
-
-    mPresentInterval = convertInterval(mSwapInterval);
+    return mMinSwapInterval;
 }
 
-DWORD Display::getPresentInterval()
+EGLint Display::getMaxSwapInterval()
 {
-    return mPresentInterval;
-}
-
-DWORD Display::convertInterval(GLint interval)
-{
-    switch(interval)
-    {
-      case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
-      case 1: return D3DPRESENT_INTERVAL_ONE;
-      case 2: return D3DPRESENT_INTERVAL_TWO;
-      case 3: return D3DPRESENT_INTERVAL_THREE;
-      case 4: return D3DPRESENT_INTERVAL_FOUR;
-      default: UNREACHABLE();
-    }
-
-    return D3DPRESENT_INTERVAL_DEFAULT;
+    return mMaxSwapInterval;
 }
 
 IDirect3DDevice9 *Display::getDevice()
 {
+    if (!mDevice)
+    {
+        if (!createDevice())
+        {
+            return NULL;
+        }
+    }
+
     return mDevice;
 }
 
@@ -487,4 +533,127 @@
 
     return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
 }
+
+bool Display::getFloatTextureSupport(bool *filtering, bool *renderable)
+{
+    D3DDISPLAYMODE currentDisplayMode;
+    mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+    *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, 
+                                                    D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
+                 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+                                                    D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+    
+    *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+                                                     D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F))&&
+                  SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+                                                     D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+
+    if (!filtering && !renderable)
+    {
+        return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, 
+                                                  D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
+               SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+                                                  D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+    }
+    else
+    {
+        return true;
+    }
 }
+
+bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable)
+{
+    D3DDISPLAYMODE currentDisplayMode;
+    mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+    *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, 
+                                                    D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
+                 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+                                                    D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+    
+    *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, 
+                                                    D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
+                 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+                                                    D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+
+    if (!filtering && !renderable)
+    {
+        return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, 
+                                                  D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
+               SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+                                                  D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+    }
+    else
+    {
+        return true;
+    }
+}
+
+bool Display::getLuminanceTextureSupport()
+{
+    D3DDISPLAYMODE currentDisplayMode;
+    mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+    return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
+}
+
+bool Display::getLuminanceAlphaTextureSupport()
+{
+    D3DDISPLAYMODE currentDisplayMode;
+    mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+    return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
+}
+
+D3DPOOL Display::getBufferPool(DWORD usage) const
+{
+    if (mD3d9ex != NULL)
+    {
+        return D3DPOOL_DEFAULT;
+    }
+    else
+    {
+        if (!(usage & D3DUSAGE_DYNAMIC))
+        {
+            return D3DPOOL_MANAGED;
+        }
+    }
+
+    return D3DPOOL_DEFAULT;
+}
+
+bool Display::getEventQuerySupport()
+{
+    IDirect3DQuery9 *query;
+    HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
+    if (SUCCEEDED(result))
+    {
+        query->Release();
+    }
+
+    return result != D3DERR_NOTAVAILABLE;
+}
+
+D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()
+{
+    D3DPRESENT_PARAMETERS presentParameters = {0};
+
+    // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
+    presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
+    presentParameters.BackBufferCount = 1;
+    presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
+    presentParameters.BackBufferWidth = 1;
+    presentParameters.BackBufferHeight = 1;
+    presentParameters.EnableAutoDepthStencil = FALSE;
+    presentParameters.Flags = 0;
+    presentParameters.hDeviceWindow = mDeviceWindow;
+    presentParameters.MultiSampleQuality = 0;
+    presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
+    presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
+    presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    presentParameters.Windowed = TRUE;
+
+    return presentParameters;
+}
+}
\ No newline at end of file
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.h b/Source/ThirdParty/ANGLE/src/libEGL/Display.h
index bd33012..4b74e1e 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Display.h
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.h
@@ -54,17 +54,25 @@
     bool isValidSurface(egl::Surface *surface);
     bool hasExistingWindowSurface(HWND window);
 
-    void setSwapInterval(GLint interval);
-    DWORD getPresentInterval();
-    static DWORD convertInterval(GLint interval);
+    EGLint getMinSwapInterval();
+    EGLint getMaxSwapInterval();
 
     virtual IDirect3DDevice9 *getDevice();
     virtual D3DCAPS9 getDeviceCaps();
     virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
     virtual bool getCompressedTextureSupport();
+    virtual bool getEventQuerySupport();
+    virtual bool getFloatTextureSupport(bool *filtering, bool *renderable);
+    virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable);
+    virtual bool getLuminanceTextureSupport();
+    virtual bool getLuminanceAlphaTextureSupport();
+    virtual D3DPOOL getBufferPool(DWORD usage) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Display);
+
+    D3DPRESENT_PARAMETERS getDefaultPresentParameters();
+
     const HDC mDc;
 
     HMODULE mD3d9Module;
@@ -78,11 +86,9 @@
     HWND mDeviceWindow;
 
     bool mSceneStarted;
-    GLint mSwapInterval;
     EGLint mMaxSwapInterval;
     EGLint mMinSwapInterval;
-    DWORD mPresentInterval;
-
+    
     typedef std::set<Surface*> SurfaceSet;
     SurfaceSet mSurfaceSet;
 
@@ -92,6 +98,7 @@
     ContextSet mContextSet;
 
     bool createDevice();
+    bool resetDevice();
 };
 }
 
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp
index a5638d4..2736a7f 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp
@@ -8,6 +8,8 @@
 // such as the client area of a window, including any back buffers.
 // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
 
+#include <tchar.h>
+
 #include "libEGL/Surface.h"
 
 #include "common/debug.h"
@@ -23,7 +25,6 @@
     mSwapChain = NULL;
     mDepthStencil = NULL;
     mBackBuffer = NULL;
-    mRenderTarget = NULL;
     mFlipTexture = NULL;
     mFlipState = NULL;
     mPreFlipState = NULL;
@@ -31,52 +32,86 @@
     mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
     mRenderBuffer = EGL_BACK_BUFFER;
     mSwapBehavior = EGL_BUFFER_PRESERVED;
+    mSwapInterval = -1;
+    setSwapInterval(1);
 
+    subclassWindow();
     resetSwapChain();
 }
 
 Surface::~Surface()
 {
+    unsubclassWindow();
+    release();
+}
+
+void Surface::release()
+{
     if (mSwapChain)
     {
         mSwapChain->Release();
+        mSwapChain = NULL;
     }
 
     if (mBackBuffer)
     {
         mBackBuffer->Release();
-    }
-
-    if (mRenderTarget)
-    {
-        mRenderTarget->Release();
+        mBackBuffer = NULL;
     }
 
     if (mDepthStencil)
     {
         mDepthStencil->Release();
+        mDepthStencil = NULL;
     }
 
     if (mFlipTexture)
     {
         mFlipTexture->Release();
+        mFlipTexture = NULL;
     }
 
     if (mFlipState)
     {
         mFlipState->Release();
+        mFlipState = NULL;
     }
 
     if (mPreFlipState)
     {
         mPreFlipState->Release();
+        mPreFlipState = NULL;
     }
 }
 
 void Surface::resetSwapChain()
 {
+    RECT windowRect;
+    if (!GetClientRect(getWindowHandle(), &windowRect))
+    {
+        ASSERT(false);
+
+        ERR("Could not retrieve the window dimensions");
+        return;
+    }
+
+    resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
+}
+
+void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
+{
     IDirect3DDevice9 *device = mDisplay->getDevice();
 
+    if (device == NULL)
+    {
+        return;
+    }
+
+    // Evict all non-render target textures to system memory and release all resources
+    // before reallocating them to free up as much video memory as possible.
+    device->EvictManagedResources();
+    release();
+    
     D3DPRESENT_PARAMETERS presentParameters = {0};
 
     presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
@@ -87,96 +122,57 @@
     presentParameters.hDeviceWindow = getWindowHandle();
     presentParameters.MultiSampleQuality = 0;                  // FIXME: Unimplemented
     presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;   // FIXME: Unimplemented
-    presentParameters.PresentationInterval = Display::convertInterval(mConfig->mMinSwapInterval);
+    presentParameters.PresentationInterval = mPresentInterval;
     presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
     presentParameters.Windowed = TRUE;
+    presentParameters.BackBufferWidth = backbufferWidth;
+    presentParameters.BackBufferHeight = backbufferHeight;
 
-    RECT windowRect;
-    if (!GetClientRect(getWindowHandle(), &windowRect))
-    {
-        ASSERT(false);
-        return;
-    }
-
-    presentParameters.BackBufferWidth = windowRect.right - windowRect.left;
-    presentParameters.BackBufferHeight = windowRect.bottom - windowRect.top;
-
-    IDirect3DSwapChain9 *swapChain = NULL;
-    HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &swapChain);
+    HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
 
     if (FAILED(result))
     {
         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
 
         ERR("Could not create additional swap chains: %08lX", result);
+        release();
         return error(EGL_BAD_ALLOC);
     }
 
-    IDirect3DSurface9 *depthStencilSurface = NULL;
     result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
                                                presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
-                                               presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
+                                               presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
 
     if (FAILED(result))
     {
         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
 
-        swapChain->Release();
-
         ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
-        return error(EGL_BAD_ALLOC);
-    }
-
-    IDirect3DSurface9 *renderTarget = NULL;
-    result = device->CreateRenderTarget(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.BackBufferFormat,
-                                        presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &renderTarget, NULL);
-
-    if (FAILED(result))
-    {
-        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-
-        swapChain->Release();
-        depthStencilSurface->Release();
-
-        ERR("Could not create render target surface for new swap chain: %08lX", result);
+        release();
         return error(EGL_BAD_ALLOC);
     }
 
     ASSERT(SUCCEEDED(result));
 
-    IDirect3DTexture9 *flipTexture = NULL;
     result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
-                                   presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &flipTexture, NULL);
+                                   presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mFlipTexture, NULL);
 
     if (FAILED(result))
     {
         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
 
-        swapChain->Release();
-        depthStencilSurface->Release();
-        renderTarget->Release();
-
         ERR("Could not create flip texture for new swap chain: %08lX", result);
+        release();
         return error(EGL_BAD_ALLOC);
     }
 
-    IDirect3DSurface9 *backBuffer = NULL;
-    swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
-
-    if (mSwapChain) mSwapChain->Release();
-    if (mDepthStencil) mDepthStencil->Release();
-    if (mBackBuffer) mBackBuffer->Release();
-    if (mRenderTarget) mRenderTarget->Release();
-    if (mFlipTexture) mFlipTexture->Release();
-
+    mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
     mWidth = presentParameters.BackBufferWidth;
     mHeight = presentParameters.BackBufferHeight;
 
-    mSwapChain = swapChain;
-    mDepthStencil = depthStencilSurface;
-    mBackBuffer = backBuffer;
-    mRenderTarget = renderTarget;
-    mFlipTexture = flipTexture;
+    mPresentIntervalDirty = false;
+
+    InvalidateRect(mWindow, NULL, FALSE);
 
     // The flip state block recorded mFlipTexture so it is now invalid.
     releaseRecordedState(device);
@@ -199,6 +195,7 @@
     device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
     device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
     device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
+    device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
     device->SetPixelShader(NULL);
     device->SetVertexShader(NULL);
 
@@ -206,7 +203,7 @@
     device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
     device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
     device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
-    device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture.
+    device->SetTexture(0, NULL);   // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture.
     device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
     device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
     device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
@@ -214,7 +211,10 @@
     device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
     device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
 
-    device->SetStreamSourceFreq(0, 1); // DrawPrimitiveUP only cares about stream 0, not the rest.
+    RECT scissorRect = {0};   // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
+    device->SetScissorRect(&scissorRect);
+    D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
+    device->SetViewport(&viewport);
 }
 
 void Surface::applyFlipState(IDirect3DDevice9 *device)
@@ -275,8 +275,6 @@
 
 void Surface::restoreState(IDirect3DDevice9 *device)
 {
-    mPreFlipState->Apply();
-
     device->SetRenderTarget(0, mPreFlipBackBuffer);
     device->SetDepthStencilSurface(mPreFlipDepthStencil);
 
@@ -291,6 +289,8 @@
         mPreFlipDepthStencil->Release();
         mPreFlipDepthStencil = NULL;
     }
+
+    mPreFlipState->Apply();
 }
 
 // On the next flip, this will cause the state to be recorded from scratch.
@@ -309,8 +309,58 @@
         mPreFlipState = NULL;
     }
 }
+#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
+#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
 
-bool Surface::checkForWindowResize()
+static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
+  if (message == WM_SIZE) {
+      Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
+      if(surf) {
+        surf->checkForOutOfDateSwapChain();
+      }
+  }
+  WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
+  return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
+}
+
+void Surface::subclassWindow()
+{
+  SetLastError(0);
+  LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc));
+  if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) {
+    mWindowSubclassed = false;
+    return;
+  }
+
+  SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+  SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+  mWindowSubclassed = true;
+}
+
+void Surface::unsubclassWindow()
+{
+  if(!mWindowSubclassed)
+    return;
+
+  // un-subclass
+  LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc));
+
+  // Check the windowproc is still SurfaceWindowProc.
+  // If this assert fails, then it is likely the application has subclassed the
+  // hwnd as well and did not unsubclass before destroying its EGL context. The
+  // application should be modified to either subclass before initializing the
+  // EGL context, or to unsubclass before destroying the EGL context.
+  if(parentWndFunc) {
+    LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc);
+    ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc));
+  }
+
+  RemoveProp(mWindow, kSurfaceProperty);
+  RemoveProp(mWindow, kParentWndProc);
+  mWindowSubclassed = false;
+}
+
+bool Surface::checkForOutOfDateSwapChain()
 {
     RECT client;
     if (!GetClientRect(getWindowHandle(), &client))
@@ -319,10 +369,14 @@
         return false;
     }
 
-    if (getWidth() != client.right - client.left || getHeight() != client.bottom - client.top)
-    {
-        resetSwapChain();
+    // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
+    int clientWidth = client.right - client.left;
+    int clientHeight = client.bottom - client.top;
+    bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
 
+    if (sizeDirty || mPresentIntervalDirty)
+    {
+        resetSwapChain(clientWidth, clientHeight);
         if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
         {
             glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
@@ -330,57 +384,51 @@
 
         return true;
     }
-
     return false;
 }
 
+DWORD Surface::convertInterval(EGLint interval)
+{
+    switch(interval)
+    {
+      case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
+      case 1: return D3DPRESENT_INTERVAL_ONE;
+      case 2: return D3DPRESENT_INTERVAL_TWO;
+      case 3: return D3DPRESENT_INTERVAL_THREE;
+      case 4: return D3DPRESENT_INTERVAL_FOUR;
+      default: UNREACHABLE();
+    }
+
+    return D3DPRESENT_INTERVAL_DEFAULT;
+}
+
+
 bool Surface::swap()
 {
     if (mSwapChain)
     {
-        IDirect3DTexture9 *flipTexture = mFlipTexture;
-        flipTexture->AddRef();
-
-        IDirect3DSurface9 *renderTarget = mRenderTarget;
-        renderTarget->AddRef();
-
-        EGLint oldWidth = mWidth;
-        EGLint oldHeight = mHeight;
-
-        checkForWindowResize();
-
         IDirect3DDevice9 *device = mDisplay->getDevice();
 
-        IDirect3DSurface9 *textureSurface;
-        flipTexture->GetSurfaceLevel(0, &textureSurface);
-
-        mDisplay->endScene();
-        device->StretchRect(renderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
-        renderTarget->Release();
-
         applyFlipState(device);
-        device->SetTexture(0, flipTexture);
-
-        float xscale = (float)mWidth / oldWidth;
-        float yscale = (float)mHeight / oldHeight;
+        device->SetTexture(0, mFlipTexture);
 
         // Render the texture upside down into the back buffer
-        // Texcoords are chosen to pin a potentially resized image into the upper-left corner without scaling.
-        float quad[4][6] = {{     0 - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 0.0f,   1.0f       },
-                            {mWidth - 0.5f,       0 - 0.5f, 0.0f, 1.0f, xscale, 1.0f       },
-                            {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, xscale, 1.0f-yscale},
-                            {     0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f,   1.0f-yscale}};   // x, y, z, rhw, u, v
+        // Texcoords are chosen to flip the renderTarget about its Y axis.
+        float w = static_cast<float>(getWidth());
+        float h = static_cast<float>(getHeight());
+        float quad[4][6] = {{0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f},
+                            {w - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f},
+                            {w - 0.5f, h - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f},
+                            {0 - 0.5f, h - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}};   // x, y, z, rhw, u, v
 
         mDisplay->startScene();
         device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
 
-        flipTexture->Release();
-        textureSurface->Release();
-
         restoreState(device);
 
         mDisplay->endScene();
-        HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, mDisplay->getPresentInterval());
+
+        HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0);
 
         if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
         {
@@ -394,6 +442,7 @@
 
         ASSERT(SUCCEEDED(result));
 
+        checkForOutOfDateSwapChain();
     }
 
     return true;
@@ -411,12 +460,14 @@
 
 IDirect3DSurface9 *Surface::getRenderTarget()
 {
-    if (mRenderTarget)
+    IDirect3DSurface9 *textureSurface = NULL;
+
+    if (mFlipTexture)
     {
-        mRenderTarget->AddRef();
+        mFlipTexture->GetSurfaceLevel(0, &textureSurface);
     }
 
-    return mRenderTarget;
+    return textureSurface;
 }
 
 IDirect3DSurface9 *Surface::getDepthStencil()
@@ -428,4 +479,19 @@
 
     return mDepthStencil;
 }
+
+void Surface::setSwapInterval(EGLint interval)
+{
+    if (mSwapInterval == interval)
+    {
+        return;
+    }
+    
+    mSwapInterval = interval;
+    mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
+    mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
+
+    mPresentInterval = convertInterval(mSwapInterval);
+    mPresentIntervalDirty = true;
+}
 }
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h
index 5bc912c..422d3d5 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h
@@ -29,6 +29,9 @@
 
     ~Surface();
 
+    void release();
+    void resetSwapChain();
+
     HWND getWindowHandle();
     bool swap();
 
@@ -38,18 +41,22 @@
     virtual IDirect3DSurface9 *getRenderTarget();
     virtual IDirect3DSurface9 *getDepthStencil();
 
-  private:
+    void setSwapInterval(EGLint interval);
+    bool checkForOutOfDateSwapChain();   // Returns true if swapchain changed due to resize or interval update
+
+private:
     DISALLOW_COPY_AND_ASSIGN(Surface);
 
     Display *const mDisplay;
     IDirect3DSwapChain9 *mSwapChain;
     IDirect3DSurface9 *mBackBuffer;
-    IDirect3DSurface9 *mRenderTarget;
     IDirect3DSurface9 *mDepthStencil;
     IDirect3DTexture9 *mFlipTexture;
 
-    void resetSwapChain();
-    bool checkForWindowResize();
+    void subclassWindow();
+    void unsubclassWindow();
+    void resetSwapChain(int backbufferWidth, int backbufferHeight);
+    static DWORD convertInterval(EGLint interval);
 
     void applyFlipState(IDirect3DDevice9 *device);
     void restoreState(IDirect3DDevice9 *device);
@@ -61,6 +68,7 @@
     IDirect3DSurface9 *mPreFlipDepthStencil;
 
     const HWND mWindow;            // Window that the surface is created for.
+    bool mWindowSubclassed;        // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
     const egl::Config *mConfig;    // EGL config surface was created with
     EGLint mHeight;                // Height of surface
     EGLint mWidth;                 // Width of surface
@@ -77,6 +85,9 @@
 //  EGLenum textureTarget;         // Type of texture: 2D or no texture
 //  EGLenum vgAlphaFormat;         // Alpha format for OpenVG
 //  EGLenum vgColorSpace;          // Color space for OpenVG
+    EGLint mSwapInterval;
+    DWORD mPresentInterval;
+    bool mPresentIntervalDirty;
 };
 }
 
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp
index 5ceb6ef..8dfe6e5 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp
+++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp
@@ -360,6 +360,8 @@
                   default:
                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
                 }
+
+                attrib_list += 2;
             }
         }
 
@@ -746,7 +748,14 @@
             return EGL_FALSE;
         }
 
-        display->setSwapInterval(interval);
+        egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
+
+        if (draw_surface == NULL)
+        {
+            return error(EGL_BAD_SURFACE, EGL_FALSE);
+        }
+        
+        draw_surface->setSwapInterval(interval);
 
         return success(EGL_TRUE);
     }
@@ -765,6 +774,28 @@
 
     try
     {
+        // Get the requested client version (default is 1) and check it is two.
+        EGLint client_version = 1;
+        if (attrib_list)
+        {
+            for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
+            {
+                if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
+                {
+                    client_version = attribute[1];
+                }
+                else
+                {
+                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+                }
+            }
+        }
+
+        if (client_version != 2)
+        {
+            return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+        }
+
         egl::Display *display = static_cast<egl::Display*>(dpy);
 
         if (!validate(display, config))
@@ -825,7 +856,7 @@
         gl::Context *context = static_cast<gl::Context*>(ctx);
         IDirect3DDevice9 *device = display->getDevice();
 
-        if (!device || device->TestCooperativeLevel() != D3D_OK)
+        if (!device || FAILED(device->TestCooperativeLevel()))
         {
             return error(EGL_CONTEXT_LOST, EGL_FALSE);
         }
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp
index 00c878f..43ed8a0 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp
@@ -382,6 +382,11 @@
 
 IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
 {
+    if (!surface)
+    {
+        return NULL;
+    }
+
     egl::Display *display = getDisplay();
     IDirect3DDevice9 *device = getDevice();
 
@@ -408,14 +413,8 @@
         return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
     }
 
-    RECT d3dSourceRect;
-    d3dSourceRect.left = sourceRect.left;
-    d3dSourceRect.right = sourceRect.right;
-    d3dSourceRect.top = sourceRect.top;
-    d3dSourceRect.bottom = sourceRect.bottom;
-
     display->endScene();
-    result = device->StretchRect(surface, &d3dSourceRect, textureSurface, NULL, D3DTEXF_NONE);
+    result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
 
     textureSurface->Release();
 
@@ -467,10 +466,8 @@
     device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
     device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
 
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS+1; i++)
-    {
-        device->SetStreamSourceFreq(i, 1);
-    }
+    RECT scissorRect = {0};   // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
+    device->SetScissorRect(&scissorRect);
 }
 
 void Blit::render()
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp
index 43993e7..17cea6c 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp
@@ -10,6 +10,10 @@
 
 #include "libGLESv2/Buffer.h"
 
+#include "libGLESv2/main.h"
+#include "libGLESv2/geometry/VertexDataManager.h"
+#include "libGLESv2/geometry/IndexDataManager.h"
+
 namespace gl
 {
 
@@ -18,11 +22,16 @@
     mContents = NULL;
     mSize = 0;
     mUsage = GL_DYNAMIC_DRAW;
+
+    mVertexBuffer = NULL;
+    mIndexBuffer = NULL;
 }
 
 Buffer::~Buffer()
 {
     delete[] mContents;
+    delete mVertexBuffer;
+    delete mIndexBuffer;
 }
 
 void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
@@ -46,11 +55,52 @@
 
     mSize = size;
     mUsage = usage;
+
+    invalidateStaticData();
+
+    if (usage == GL_STATIC_DRAW)
+    {
+        mVertexBuffer = new StaticVertexBuffer(getDevice());
+        mIndexBuffer = new StaticIndexBuffer(getDevice());
+    }
 }
 
 void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
 {
     memcpy(mContents + offset, data, size);
+
+    if ((mVertexBuffer && mVertexBuffer->size() != 0) || (mIndexBuffer && mIndexBuffer->size() != 0))
+    {
+        invalidateStaticData();
+
+        if (mUsage == GL_STATIC_DRAW)
+        {
+            // If applications update the buffer data after it has already been used in a draw call,
+            // it most likely isn't used as a static buffer so we should fall back to streaming usage
+            // for best performance. So ignore the usage hint and don't create new static buffers.
+        //  mVertexBuffer = new StaticVertexBuffer(getDevice());
+        //  mIndexBuffer = new StaticIndexBuffer(getDevice());
+        }
+    }
+}
+
+StaticVertexBuffer *Buffer::getVertexBuffer()
+{
+    return mVertexBuffer;
+}
+
+StaticIndexBuffer *Buffer::getIndexBuffer()
+{
+    return mIndexBuffer;
+}
+
+void Buffer::invalidateStaticData()
+{
+    delete mVertexBuffer;
+    mVertexBuffer = NULL;
+
+    delete mIndexBuffer;
+    mIndexBuffer = NULL;
 }
 
 }
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h
index 5611cc9..c2ed60f 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h
@@ -22,6 +22,8 @@
 
 namespace gl
 {
+class StaticVertexBuffer;
+class StaticIndexBuffer;
 
 class Buffer : public RefCountObject
 {
@@ -37,12 +39,19 @@
     size_t size() const { return mSize; }
     GLenum usage() const { return mUsage; }
 
+    StaticVertexBuffer *getVertexBuffer();
+    StaticIndexBuffer *getIndexBuffer();
+    void invalidateStaticData();
+
   private:
     DISALLOW_COPY_AND_ASSIGN(Buffer);
 
     GLubyte *mContents;
     size_t mSize;
     GLenum mUsage;
+
+    StaticVertexBuffer *mVertexBuffer;
+    StaticIndexBuffer *mIndexBuffer;
 };
 
 }
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp
index 48ef8fc..9be59c4 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp
@@ -19,15 +19,14 @@
 #include "libGLESv2/Blit.h"
 #include "libGLESv2/ResourceManager.h"
 #include "libGLESv2/Buffer.h"
+#include "libGLESv2/Fence.h"
 #include "libGLESv2/FrameBuffer.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/RenderBuffer.h"
 #include "libGLESv2/Shader.h"
 #include "libGLESv2/Texture.h"
-#include "libGLESv2/geometry/backend.h"
 #include "libGLESv2/geometry/VertexDataManager.h"
 #include "libGLESv2/geometry/IndexDataManager.h"
-#include "libGLESv2/geometry/dx9.h"
 
 #undef near
 #undef far
@@ -83,6 +82,7 @@
     mState.scissorTest = false;
     mState.dither = true;
     mState.generateMipmapHint = GL_DONT_CARE;
+    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
 
     mState.lineWidth = 1.0f;
 
@@ -120,11 +120,8 @@
     // In order that access to these initial textures not be lost, they are treated as texture
     // objects all of whose names are 0.
 
-    mTexture2DZero = new Texture2D(0);
-    mTextureCubeMapZero = new TextureCubeMap(0);
-
-    mColorbufferZero = NULL;
-    mDepthStencilbufferZero = NULL;
+    mTexture2DZero.set(new Texture2D(0));
+    mTextureCubeMapZero.set(new TextureCubeMap(0));
 
     mState.activeSampler = 0;
     bindArrayBuffer(0);
@@ -135,17 +132,11 @@
     bindDrawFramebuffer(0);
     bindRenderbuffer(0);
 
-    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
-    {
-        mIncompleteTextures[type] = NULL;
-    }
-
     mState.currentProgram = 0;
 
     mState.packAlignment = 4;
     mState.unpackAlignment = 4;
 
-    mBufferBackEnd = NULL;
     mVertexDataManager = NULL;
     mIndexDataManager = NULL;
     mBlit = NULL;
@@ -158,6 +149,8 @@
 
     mHasBeenCurrent = false;
 
+    mSupportsCompressedTextures = false;
+    mSupportsEventQueries = false;
     mMaxSupportedSamples = 0;
     mMaskedClearSavedState = NULL;
     markAllStateDirty();
@@ -180,6 +173,11 @@
         deleteFramebuffer(mFramebufferMap.begin()->first);
     }
 
+    while (!mFenceMap.empty())
+    {
+        deleteFence(mFenceMap.begin()->first);
+    }
+
     while (!mMultiSampleSupport.empty())
     {
         delete [] mMultiSampleSupport.begin()->second;
@@ -196,7 +194,7 @@
 
     for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
     {
-        delete mIncompleteTextures[type];
+        mIncompleteTextures[type].set(NULL);
     }
 
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
@@ -206,14 +204,11 @@
 
     mState.arrayBuffer.set(NULL);
     mState.elementArrayBuffer.set(NULL);
-    mState.texture2D.set(NULL);
-    mState.textureCubeMap.set(NULL);
     mState.renderbuffer.set(NULL);
 
-    delete mTexture2DZero;
-    delete mTextureCubeMapZero;
+    mTexture2DZero.set(NULL);
+    mTextureCubeMapZero.set(NULL);
 
-    delete mBufferBackEnd;
     delete mVertexDataManager;
     delete mIndexDataManager;
     delete mBlit;
@@ -234,11 +229,20 @@
     {
         mDeviceCaps = display->getDeviceCaps();
 
-        mBufferBackEnd = new Dx9BackEnd(this, device);
-        mVertexDataManager = new VertexDataManager(this, mBufferBackEnd);
-        mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
+        mVertexDataManager = new VertexDataManager(this, device);
+        mIndexDataManager = new IndexDataManager(this, device);
         mBlit = new Blit(this);
 
+        mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
+
+        mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight),
+                                        (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
+        mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
+        mMaxRenderbufferDimension = mMaxTextureDimension;
+        mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
+        TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d",
+              mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel);
+
         const D3DFORMAT renderBufferFormats[] =
         {
             D3DFMT_A8R8G8B8,
@@ -265,7 +269,14 @@
 
         mMaxSupportedSamples = max;
 
+        mSupportsEventQueries = display->getEventQuerySupport();
         mSupportsCompressedTextures = display->getCompressedTextureSupport();
+        mSupportsFloatTextures = display->getFloatTextureSupport(&mSupportsFloatLinearFilter, &mSupportsFloatRenderableTextures);
+        mSupportsHalfFloatTextures = display->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter, &mSupportsHalfFloatRenderableTextures);
+        mSupportsLuminanceTextures = display->getLuminanceTextureSupport();
+        mSupportsLuminanceAlphaTextures = display->getLuminanceAlphaTextureSupport();
+
+        mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16);
 
         initExtensionString();
 
@@ -292,15 +303,16 @@
 
     setFramebufferZero(framebufferZero);
 
-    defaultRenderTarget->Release();
+    if (defaultRenderTarget)
+    {
+        defaultRenderTarget->Release();
+    }
 
     if (depthStencil)
     {
         depthStencil->Release();
     }
     
-    mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
-
     markAllStateDirty();
 }
 
@@ -309,6 +321,8 @@
 {
     mAppliedRenderTargetSerial = 0;
     mAppliedDepthbufferSerial = 0;
+    mAppliedStencilbufferSerial = 0;
+    mDepthStencilInitialized = false;
     mAppliedProgram = 0;
 
     mClearStateDirty = true;
@@ -322,11 +336,6 @@
     mSampleStateDirty = true;
     mDitherStateDirty = true;
     mFrontFaceDirty = true;
-
-    if (mBufferBackEnd != NULL)
-    {
-        mBufferBackEnd->invalidate();
-    }
 }
 
 void Context::setClearColor(float red, float green, float blue, float alpha)
@@ -650,6 +659,14 @@
     mState.generateMipmapHint = hint;
 }
 
+void Context::setFragmentShaderDerivativeHint(GLenum hint)
+{
+    mState.fragmentShaderDerivativeHint = hint;
+    // TODO: Propagate the hint to shader translator so we can write
+    // ddx, ddx_coarse, or ddx_fine depending on the hint.
+    // Ignore for now. It is valid for implementations to ignore hint.
+}
+
 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
 {
     mState.viewportX = x;
@@ -718,12 +735,12 @@
     return mState.arrayBuffer.id();
 }
 
-void Context::setVertexAttribEnabled(unsigned int attribNum, bool enabled)
+void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
 {
-    mState.vertexAttribute[attribNum].mEnabled = enabled;
+    mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
 }
 
-const AttributeState &Context::getVertexAttribState(unsigned int attribNum)
+const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
 {
     return mState.vertexAttribute[attribNum];
 }
@@ -744,8 +761,7 @@
     return mState.vertexAttribute[attribNum].mPointer;
 }
 
-// returns entire set of attributes as a block
-const AttributeState *Context::getVertexAttribBlock()
+const VertexAttributeArray &Context::getVertexAttributes()
 {
     return mState.vertexAttribute;
 }
@@ -810,6 +826,20 @@
     return handle;
 }
 
+GLuint Context::createFence()
+{
+    unsigned int handle = 0;
+
+    while (mFenceMap.find(handle) != mFenceMap.end())
+    {
+        handle++;
+    }
+
+    mFenceMap[handle] = new Fence;
+
+    return handle;
+}
+
 void Context::deleteBuffer(GLuint buffer)
 {
     if (mResourceManager->getBuffer(buffer))
@@ -863,6 +893,17 @@
     }
 }
 
+void Context::deleteFence(GLuint fence)
+{
+    FenceMap::iterator fenceObject = mFenceMap.find(fence);
+
+    if (fenceObject != mFenceMap.end())
+    {
+        delete fenceObject->second;
+        mFenceMap.erase(fenceObject);
+    }
+}
+
 Buffer *Context::getBuffer(GLuint handle)
 {
     return mResourceManager->getBuffer(handle);
@@ -916,18 +957,14 @@
 {
     mResourceManager->checkTextureAllocation(texture, SAMPLER_2D);
 
-    mState.texture2D.set(getTexture(texture));
-
-    mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(mState.texture2D.get());
+    mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(getTexture(texture));
 }
 
 void Context::bindTextureCubeMap(GLuint texture)
 {
     mResourceManager->checkTextureAllocation(texture, SAMPLER_CUBE);
 
-    mState.textureCubeMap.set(getTexture(texture));
-
-    mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(mState.textureCubeMap.get());
+    mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(getTexture(texture));
 }
 
 void Context::bindReadFramebuffer(GLuint framebuffer)
@@ -1005,6 +1042,20 @@
     }
 }
 
+Fence *Context::getFence(unsigned int handle)
+{
+    FenceMap::iterator fence = mFenceMap.find(handle);
+
+    if (fence == mFenceMap.end())
+    {
+        return NULL;
+    }
+    else
+    {
+        return fence->second;
+    }
+}
+
 Buffer *Context::getArrayBuffer()
 {
     return mState.arrayBuffer.get();
@@ -1022,35 +1073,25 @@
 
 Texture2D *Context::getTexture2D()
 {
-    if (mState.texture2D.id() == 0)   // Special case: 0 refers to different initial textures based on the target
-    {
-        return mTexture2DZero;
-    }
-
-    return static_cast<Texture2D*>(mState.texture2D.get());
+    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, SAMPLER_2D));
 }
 
 TextureCubeMap *Context::getTextureCubeMap()
 {
-    if (mState.textureCubeMap.id() == 0)   // Special case: 0 refers to different initial textures based on the target
-    {
-        return mTextureCubeMapZero;
-    }
-
-    return static_cast<TextureCubeMap*>(mState.textureCubeMap.get());
+    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, SAMPLER_CUBE));
 }
 
 Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
 {
     GLuint texid = mState.samplerTexture[type][sampler].id();
 
-    if (texid == 0)
+    if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
     {
         switch (type)
         {
           default: UNREACHABLE();
-          case SAMPLER_2D: return mTexture2DZero;
-          case SAMPLER_CUBE: return mTextureCubeMapZero;
+          case SAMPLER_2D: return mTexture2DZero.get();
+          case SAMPLER_CUBE: return mTextureCubeMapZero.get();
         }
     }
 
@@ -1070,15 +1111,15 @@
         params[2] = mState.colorMaskBlue;
         params[3] = mState.colorMaskAlpha;
         break;
-      case GL_CULL_FACE:                *params = mState.cullFace;
-      case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFill;
-      case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage;
-      case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverage;
-      case GL_SCISSOR_TEST:             *params = mState.scissorTest;
-      case GL_STENCIL_TEST:             *params = mState.stencilTest;
-      case GL_DEPTH_TEST:               *params = mState.depthTest;
-      case GL_BLEND:                    *params = mState.blend;
-      case GL_DITHER:                   *params = mState.dither;
+      case GL_CULL_FACE:                *params = mState.cullFace;                  break;
+      case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFill;         break;
+      case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage;     break;
+      case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverage;            break;
+      case GL_SCISSOR_TEST:             *params = mState.scissorTest;               break;
+      case GL_STENCIL_TEST:             *params = mState.stencilTest;               break;
+      case GL_DEPTH_TEST:               *params = mState.depthTest;                 break;
+      case GL_BLEND:                    *params = mState.blend;                     break;
+      case GL_DITHER:                   *params = mState.dither;                    break;
       default:
         return false;
     }
@@ -1141,24 +1182,25 @@
     {
       case GL_MAX_VERTEX_ATTRIBS:               *params = gl::MAX_VERTEX_ATTRIBS;               break;
       case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = gl::MAX_VERTEX_UNIFORM_VECTORS;       break;
-      case GL_MAX_VARYING_VECTORS:              *params = gl::MAX_VARYING_VECTORS;              break;
+      case GL_MAX_VARYING_VECTORS:              *params = getMaximumVaryingVectors();           break;
       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
       case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
-      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = gl::MAX_FRAGMENT_UNIFORM_VECTORS;     break;
-      case GL_MAX_RENDERBUFFER_SIZE:            *params = gl::MAX_RENDERBUFFER_SIZE;            break;
+      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = getMaximumFragmentUniformVectors();   break;
+      case GL_MAX_RENDERBUFFER_SIZE:            *params = getMaximumRenderbufferDimension();    break;
       case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
       case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
       case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.id();              break;
       case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.id();       break;
-      //case GL_FRAMEBUFFER_BINDING:              // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
-      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:     *params = mState.drawFramebuffer;               break;
-      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:     *params = mState.readFramebuffer;               break;
+      //case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
+      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
       case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.id();             break;
       case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
       case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
       case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
       case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
+      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
       case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
       case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
       case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
@@ -1183,8 +1225,8 @@
       case GL_STENCIL_BACK_WRITEMASK:           *params = mState.stencilBackWritemask;          break;
       case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
       case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
-      case GL_MAX_TEXTURE_SIZE:                 *params = gl::MAX_TEXTURE_SIZE;                 break;
-      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = gl::MAX_CUBE_MAP_TEXTURE_SIZE;        break;
+      case GL_MAX_TEXTURE_SIZE:                 *params = getMaximumTextureDimension();         break;
+      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = getMaximumCubeTextureDimension();     break;
       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   
         {
             if (supportsCompressedTextures())
@@ -1246,7 +1288,7 @@
       case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = gl::IMPLEMENTATION_COLOR_READ_FORMAT; break;
       case GL_MAX_VIEWPORT_DIMS:
         {
-            int maxDimension = std::max((int)gl::MAX_RENDERBUFFER_SIZE, (int)gl::MAX_TEXTURE_SIZE);
+            int maxDimension = std::max(getMaximumRenderbufferDimension(), getMaximumTextureDimension());
             params[0] = maxDimension;
             params[1] = maxDimension;
         }
@@ -1392,6 +1434,7 @@
       case GL_PACK_ALIGNMENT:
       case GL_UNPACK_ALIGNMENT:
       case GL_GENERATE_MIPMAP_HINT:
+      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
       case GL_RED_BITS:
       case GL_GREEN_BITS:
       case GL_BLUE_BITS:
@@ -1535,6 +1578,12 @@
     }
 
     IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
+
+    if (!renderTarget)
+    {
+        return false;   // Context must be lost
+    }
+
     IDirect3DSurface9 *depthStencil = NULL;
 
     unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
@@ -1550,26 +1599,43 @@
     if (framebufferObject->getDepthbufferType() != GL_NONE)
     {
         depthStencil = framebufferObject->getDepthbuffer()->getDepthStencil();
+        if (!depthStencil)
+        {
+            ERR("Depth stencil pointer unexpectedly null.");
+            return false;
+        }
+        
         depthbufferSerial = framebufferObject->getDepthbuffer()->getSerial();
     }
     else if (framebufferObject->getStencilbufferType() != GL_NONE)
     {
         depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+        if (!depthStencil)
+        {
+            ERR("Depth stencil pointer unexpectedly null.");
+            return false;
+        }
+        
         stencilbufferSerial = framebufferObject->getStencilbuffer()->getSerial();
     }
 
     if (depthbufferSerial != mAppliedDepthbufferSerial ||
-        stencilbufferSerial != mAppliedStencilbufferSerial)
+        stencilbufferSerial != mAppliedStencilbufferSerial ||
+        !mDepthStencilInitialized)
     {
         device->SetDepthStencilSurface(depthStencil);
         mAppliedDepthbufferSerial = depthbufferSerial;
         mAppliedStencilbufferSerial = stencilbufferSerial;
+        mDepthStencilInitialized = true;
     }
 
     D3DVIEWPORT9 viewport;
     D3DSURFACE_DESC desc;
     renderTarget->GetDesc(&desc);
 
+    float zNear = clamp01(mState.zNear);
+    float zFar = clamp01(mState.zFar);
+
     if (ignoreViewport)
     {
         viewport.X = 0;
@@ -1585,8 +1651,8 @@
         viewport.Y = std::max(mState.viewportY, 0);
         viewport.Width = std::min(mState.viewportWidth, (int)desc.Width - (int)viewport.X);
         viewport.Height = std::min(mState.viewportHeight, (int)desc.Height - (int)viewport.Y);
-        viewport.MinZ = clamp01(mState.zNear);
-        viewport.MaxZ = clamp01(mState.zFar);
+        viewport.MinZ = zNear;
+        viewport.MaxZ = zFar;
     }
 
     if (viewport.Width <= 0 || viewport.Height <= 0)
@@ -1623,27 +1689,21 @@
 
         GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation();
         GLfloat xy[2] = {1.0f / viewport.Width, 1.0f / viewport.Height};
-        programObject->setUniform2fv(halfPixelSize, 1, (GLfloat*)&xy);
+        programObject->setUniform2fv(halfPixelSize, 1, xy);
 
-        GLint window = programObject->getDxViewportLocation();
+        GLint viewport = programObject->getDxViewportLocation();
         GLfloat whxy[4] = {mState.viewportWidth / 2.0f, mState.viewportHeight / 2.0f, 
                           (float)mState.viewportX + mState.viewportWidth / 2.0f, 
                           (float)mState.viewportY + mState.viewportHeight / 2.0f};
-        programObject->setUniform4fv(window, 1, (GLfloat*)&whxy);
+        programObject->setUniform4fv(viewport, 1, whxy);
 
         GLint depth = programObject->getDxDepthLocation();
-        GLfloat dz[2] = {(mState.zFar - mState.zNear) / 2.0f, (mState.zNear + mState.zFar) / 2.0f};
-        programObject->setUniform2fv(depth, 1, (GLfloat*)&dz);
+        GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f};
+        programObject->setUniform2fv(depth, 1, dz);
 
-        GLint near = programObject->getDepthRangeNearLocation();
-        programObject->setUniform1fv(near, 1, &mState.zNear);
-
-        GLint far = programObject->getDepthRangeFarLocation();
-        programObject->setUniform1fv(far, 1, &mState.zFar);
-
-        GLint diff = programObject->getDepthRangeDiffLocation();
-        GLfloat zDiff = mState.zFar - mState.zNear;
-        programObject->setUniform1fv(diff, 1, &zDiff);
+        GLint depthRange = programObject->getDxDepthRangeLocation();
+        GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
+        programObject->setUniform3fv(depthRange, 1, nearFarDiff);
     }
 
     return true;
@@ -1830,39 +1890,46 @@
         mPolygonOffsetStateDirty = false;
     }
 
-    if (framebufferObject->isMultisample() && mSampleStateDirty)
+    if (mSampleStateDirty)
     {
-        if (mState.sampleAlphaToCoverage)
+        if (framebufferObject->isMultisample())
         {
-            FIXME("Sample alpha to coverage is unimplemented.");
-        }
-
-        if (mState.sampleCoverage)
-        {
-            device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
-            unsigned int mask = 0;
-            if (mState.sampleCoverageValue != 0)
+            if (mState.sampleAlphaToCoverage)
             {
-                float threshold = 0.5f;
+                FIXME("Sample alpha to coverage is unimplemented.");
+            }
 
-                for (int i = 0; i < framebufferObject->getSamples(); ++i)
+            device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+            if (mState.sampleCoverage)
+            {
+                unsigned int mask = 0;
+                if (mState.sampleCoverageValue != 0)
                 {
-                    mask <<= 1;
+                    float threshold = 0.5f;
 
-                    if ((i + 1) * mState.sampleCoverageValue >= threshold)
+                    for (int i = 0; i < framebufferObject->getSamples(); ++i)
                     {
-                        threshold += 1.0f;
-                        mask |= 1;
+                        mask <<= 1;
+
+                        if ((i + 1) * mState.sampleCoverageValue >= threshold)
+                        {
+                            threshold += 1.0f;
+                            mask |= 1;
+                        }
                     }
                 }
-            }
-            
-            if (mState.sampleCoverageInvert)
-            {
-                mask = ~mask;
-            }
+                
+                if (mState.sampleCoverageInvert)
+                {
+                    mask = ~mask;
+                }
 
-            device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
+                device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
+            }
+            else
+            {
+                device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+            }
         }
         else
         {
@@ -1887,18 +1954,18 @@
 {
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
-        if (attributes[i].enabled)
+        if (attributes[i].active)
         {
             attributes[i].semanticIndex = getCurrentProgram()->getSemanticIndex(i);
         }
     }
 }
 
-GLenum Context::applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool *useIndexing, TranslatedIndexData *indexInfo)
+GLenum Context::applyVertexBuffer(GLint first, GLsizei count)
 {
     TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
 
-    GLenum err = mVertexDataManager->preRenderValidate(first, count, translated);
+    GLenum err = mVertexDataManager->prepareVertexData(first, count, translated);
     if (err != GL_NO_ERROR)
     {
         return err;
@@ -1906,53 +1973,20 @@
 
     lookupAttributeMapping(translated);
 
-    mBufferBackEnd->setupAttributesPreDraw(translated);
+    mVertexDataManager->setupAttributes(translated);
 
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (translated[i].enabled && translated[i].nonArray)
-        {
-            err = mIndexDataManager->preRenderValidateUnindexed(mode, count, indexInfo);
-            if (err != GL_NO_ERROR)
-            {
-                return err;
-            }
-
-            mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
-
-            *useIndexing = true;
-            return GL_NO_ERROR;
-        }
-    }
-
-    *useIndexing = false;
     return GL_NO_ERROR;
 }
 
-GLenum Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
-{
-    TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
-
-    GLenum err = mVertexDataManager->preRenderValidate(indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, translated);
-
-    if (err == GL_NO_ERROR)
-    {
-        lookupAttributeMapping(translated);
-
-        mBufferBackEnd->setupAttributesPreDraw(translated);
-    }
-
-    return err;
-}
-
 // Applies the indices and element array bindings to the Direct3D 9 device
 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
 {
-    GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
+    IDirect3DDevice9 *device = getDevice();
+    GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
 
     if (err == GL_NO_ERROR)
     {
-        mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
+        device->SetIndices(indexInfo->indexBuffer);
     }
 
     return err;
@@ -2048,6 +2082,12 @@
     }
 
     IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
+
+    if (!renderTarget)
+    {
+        return;   // Context must be lost, return silently
+    }
+
     IDirect3DDevice9 *device = getDevice();
 
     D3DSURFACE_DESC desc;
@@ -2141,16 +2181,6 @@
                     r = (rgb & 0xF800) * (1.0f / 0xF800);
                 }
                 break;
-              case D3DFMT_X1R5G5B5:
-                {
-                    unsigned short xrgb = *(unsigned short*)(source + 2 * i + j * lock.Pitch);
-
-                    a = 1.0f;
-                    b = (xrgb & 0x001F) * (1.0f / 0x001F);
-                    g = (xrgb & 0x03E0) * (1.0f / 0x03E0);
-                    r = (xrgb & 0x7C00) * (1.0f / 0x7C00);
-                }
-                break;
               case D3DFMT_A1R5G5B5:
                 {
                     unsigned short argb = *(unsigned short*)(source + 2 * i + j * lock.Pitch);
@@ -2191,6 +2221,28 @@
                     r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
                 }
                 break;
+              case D3DFMT_A32B32G32R32F:
+                {
+                    // float formats in D3D are stored rgba, rather than the other way round
+                    r = *((float*)(source + 16 * i + j * lock.Pitch) + 0);
+                    g = *((float*)(source + 16 * i + j * lock.Pitch) + 1);
+                    b = *((float*)(source + 16 * i + j * lock.Pitch) + 2);
+                    a = *((float*)(source + 16 * i + j * lock.Pitch) + 3);
+                }
+                break;
+              case D3DFMT_A16B16G16R16F:
+                {
+                    // float formats in D3D are stored rgba, rather than the other way round
+                    float abgr[4];
+
+                    D3DXFloat16To32Array(abgr, (D3DXFLOAT16*)(source + 8 * i + j * lock.Pitch), 4);
+
+                    a = abgr[3];
+                    b = abgr[2];
+                    g = abgr[1];
+                    r = abgr[0];
+                }
+                break;
               default:
                 UNIMPLEMENTED();   // FIXME
                 UNREACHABLE();
@@ -2314,6 +2366,12 @@
         if (framebufferObject->getStencilbufferType() != GL_NONE)
         {
             IDirect3DSurface9 *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+            if (!depthStencil)
+            {
+                ERR("Depth stencil pointer unexpectedly null.");
+                return;
+            }
+            
             D3DSURFACE_DESC desc;
             depthStencil->GetDesc(&desc);
 
@@ -2346,6 +2404,11 @@
 
     IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
 
+    if (!renderTarget)
+    {
+        return;   // Context must be lost, return silently
+    }
+
     D3DSURFACE_DESC desc;
     renderTarget->GetDesc(&desc);
 
@@ -2381,7 +2444,7 @@
             device->SetPixelShader(NULL);
             device->SetVertexShader(NULL);
             device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
-            device->SetStreamSourceFreq(0, 1);
+            device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
 
             hr = device->EndStateBlock(&mMaskedClearSavedState);
             ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
@@ -2436,7 +2499,7 @@
         device->SetPixelShader(NULL);
         device->SetVertexShader(NULL);
         device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
-        device->SetStreamSourceFreq(0, 1);
+        device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
 
         struct Vertex
         {
@@ -2517,9 +2580,7 @@
 
     applyState(mode);
 
-    TranslatedIndexData indexInfo;
-    bool useIndexing;
-    GLenum err = applyVertexBuffer(mode, first, count, &useIndexing, &indexInfo);
+    GLenum err = applyVertexBuffer(first, count);
     if (err != GL_NO_ERROR)
     {
         return error(err);
@@ -2536,18 +2597,17 @@
     if (!cullSkipsDraw(mode))
     {
         display->startScene();
-        if (useIndexing)
+        
+        device->DrawPrimitive(primitiveType, 0, primitiveCount);
+
+        if (mode == GL_LINE_LOOP)   // Draw the last segment separately
         {
-            device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/indexInfo.indexSize, primitiveCount);
-        }
-        else
-        {
-            device->DrawPrimitive(primitiveType, 0, primitiveCount);
+            drawClosingLine(first, first + count - 1);
         }
     }
 }
 
-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
+void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
 {
     if (!mState.currentProgram)
     {
@@ -2586,7 +2646,8 @@
         return error(err);
     }
 
-    err = applyVertexBuffer(indexInfo);
+    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
+    err = applyVertexBuffer(indexInfo.minIndex, vertexCount);
     if (err != GL_NO_ERROR)
     {
         return error(err);
@@ -2603,7 +2664,13 @@
     if (!cullSkipsDraw(mode))
     {
         display->startScene();
-        device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/indexInfo.indexSize, primitiveCount);
+
+        device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
+
+        if (mode == GL_LINE_LOOP)   // Draw the last segment separately
+        {
+            drawClosingLine(count, type, indices);
+        }
     }
 }
 
@@ -2631,7 +2698,6 @@
         ASSERT(SUCCEEDED(result));
 
         // Render something outside the render target
-        device->SetStreamSourceFreq(0, 1);
         device->SetPixelShader(NULL);
         device->SetVertexShader(NULL);
         device->SetFVF(D3DFVF_XYZRHW);
@@ -2687,6 +2753,93 @@
     }
 }
 
+void Context::drawClosingLine(unsigned int first, unsigned int last)
+{
+    IDirect3DDevice9 *device = getDevice();
+    IDirect3DIndexBuffer9 *indexBuffer = NULL;
+    HRESULT result = D3DERR_INVALIDCALL;
+
+    if (supports32bitIndices())
+    {
+        result = device->CreateIndexBuffer(8, D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &indexBuffer, 0);
+
+        if (SUCCEEDED(result))
+        {
+            unsigned int *data;
+            result = indexBuffer->Lock(0, 0, (void**)&data, 0);
+
+            if (SUCCEEDED(result))
+            {
+                data[0] = last;
+                data[1] = first;
+            }
+        }
+    }
+    else
+    {
+        result = device->CreateIndexBuffer(4, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &indexBuffer, 0);
+
+        if (SUCCEEDED(result))
+        {
+            unsigned short *data;
+            result = indexBuffer->Lock(0, 0, (void**)&data, 0);
+
+            if (SUCCEEDED(result))
+            {
+                data[0] = last;
+                data[1] = first;
+            }
+        }
+    }
+    
+    if (SUCCEEDED(result))
+    {
+        indexBuffer->Unlock();
+        device->SetIndices(indexBuffer);
+
+        device->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, 2, 0, 1);
+
+        indexBuffer->Release();
+    }
+    else
+    {
+        ERR("Could not create an index buffer for closing a line loop.");
+        error(GL_OUT_OF_MEMORY);
+    }
+}
+
+void Context::drawClosingLine(GLsizei count, GLenum type, const void *indices)
+{
+    unsigned int first = 0;
+    unsigned int last = 0;
+
+    if (mState.elementArrayBuffer.get())
+    {
+        Buffer *indexBuffer = mState.elementArrayBuffer.get();
+        intptr_t offset = reinterpret_cast<intptr_t>(indices);
+        indices = static_cast<const GLubyte*>(indexBuffer->data()) + offset;
+    }
+
+    switch (type)
+    {
+      case GL_UNSIGNED_BYTE:
+        first = static_cast<const GLubyte*>(indices)[0];
+        last = static_cast<const GLubyte*>(indices)[count - 1];
+        break;
+      case GL_UNSIGNED_SHORT:
+        first = static_cast<const GLushort*>(indices)[0];
+        last = static_cast<const GLushort*>(indices)[count - 1];
+        break;
+      case GL_UNSIGNED_INT:
+        first = static_cast<const GLuint*>(indices)[0];
+        last = static_cast<const GLuint*>(indices)[count - 1];
+        break;
+      default: UNREACHABLE();
+    }
+
+    drawClosingLine(first, last);
+}
+
 void Context::recordInvalidEnum()
 {
     mInvalidEnum = true;
@@ -2759,6 +2912,16 @@
     return mSupportsShaderModel3;
 }
 
+int Context::getMaximumVaryingVectors() const
+{
+    return mSupportsShaderModel3 ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2;
+}
+
+int Context::getMaximumFragmentUniformVectors() const
+{
+    return mSupportsShaderModel3 ? MAX_FRAGMENT_UNIFORM_VECTORS_SM3 : MAX_FRAGMENT_UNIFORM_VECTORS_SM2;
+}
+
 int Context::getMaxSupportedSamples() const
 {
     return mMaxSupportedSamples;
@@ -2788,11 +2951,81 @@
     return -1;
 }
 
+bool Context::supportsEventQueries() const
+{
+    return mSupportsEventQueries;
+}
+
 bool Context::supportsCompressedTextures() const
 {
     return mSupportsCompressedTextures;
 }
 
+bool Context::supportsFloatTextures() const
+{
+    return mSupportsFloatTextures;
+}
+
+bool Context::supportsFloatLinearFilter() const
+{
+    return mSupportsFloatLinearFilter;
+}
+
+bool Context::supportsFloatRenderableTextures() const
+{
+    return mSupportsFloatRenderableTextures;
+}
+
+bool Context::supportsHalfFloatTextures() const
+{
+    return mSupportsHalfFloatTextures;
+}
+
+bool Context::supportsHalfFloatLinearFilter() const
+{
+    return mSupportsHalfFloatLinearFilter;
+}
+
+bool Context::supportsHalfFloatRenderableTextures() const
+{
+    return mSupportsHalfFloatRenderableTextures;
+}
+
+int Context::getMaximumRenderbufferDimension() const
+{
+    return mMaxRenderbufferDimension;
+}
+
+int Context::getMaximumTextureDimension() const
+{
+    return mMaxTextureDimension;
+}
+
+int Context::getMaximumCubeTextureDimension() const
+{
+    return mMaxCubeTextureDimension;
+}
+
+int Context::getMaximumTextureLevel() const
+{
+    return mMaxTextureLevel;
+}
+
+bool Context::supportsLuminanceTextures() const
+{
+    return mSupportsLuminanceTextures;
+}
+
+bool Context::supportsLuminanceAlphaTextures() const
+{
+    return mSupportsLuminanceAlphaTextures;
+}
+
+bool Context::supports32bitIndices() const
+{
+    return mSupports32bitIndices;
+}
+
 void Context::detachBuffer(GLuint buffer)
 {
     // [OpenGL ES 2.0.24] section 2.9 page 22:
@@ -2903,7 +3136,7 @@
 
 Texture *Context::getIncompleteTexture(SamplerType type)
 {
-    Texture *t = mIncompleteTextures[type];
+    Texture *t = mIncompleteTextures[type].get();
 
     if (t == NULL)
     {
@@ -2939,7 +3172,7 @@
             break;
         }
 
-        mIncompleteTextures[type] = t;
+        mIncompleteTextures[type].set(t);
     }
 
     return t;
@@ -2978,7 +3211,7 @@
     mState.vertexAttribute[index].mCurrentValue[2] = values[2];
     mState.vertexAttribute[index].mCurrentValue[3] = values[3];
 
-    mVertexDataManager->dirtyCurrentValues();
+    mVertexDataManager->dirtyCurrentValue(index);
 }
 
 void Context::initExtensionString()
@@ -2988,18 +3221,44 @@
     mExtensionString += "GL_EXT_read_format_bgra ";
     mExtensionString += "GL_ANGLE_framebuffer_blit ";
     mExtensionString += "GL_OES_rgb8_rgba8 ";
+    mExtensionString += "GL_OES_standard_derivatives ";
+
+    if (supportsEventQueries())
+    {
+        mExtensionString += "GL_NV_fence ";
+    }
 
     if (supportsCompressedTextures())
     {
         mExtensionString += "GL_EXT_texture_compression_dxt1 ";
     }
 
+    if (supportsFloatTextures())
+    {
+        mExtensionString += "GL_OES_texture_float ";
+    }
+
+    if (supportsHalfFloatTextures())
+    {
+        mExtensionString += "GL_OES_texture_half_float ";
+    }
+
+    if (supportsFloatLinearFilter())
+    {
+        mExtensionString += "GL_OES_texture_float_linear ";
+    }
+
+    if (supportsHalfFloatLinearFilter())
+    {
+        mExtensionString += "GL_OES_texture_half_float_linear ";
+    }
+
     if (getMaxSupportedSamples() != 0)
     {
         mExtensionString += "GL_ANGLE_framebuffer_multisample ";
     }
 
-    if (mBufferBackEnd->supportIntIndices())
+    if (supports32bitIndices())
     {
         mExtensionString += "GL_OES_element_index_uint ";
     }
@@ -3178,10 +3437,10 @@
     }
 
     bool partialBufferCopy = false;
-    if (sourceTrimmedRect.bottom - sourceTrimmedRect.top < readFramebuffer->getColorbuffer()->getHeight() ||
-        sourceTrimmedRect.right - sourceTrimmedRect.left < readFramebuffer->getColorbuffer()->getWidth() || 
-        destTrimmedRect.bottom - destTrimmedRect.top < drawFramebuffer->getColorbuffer()->getHeight() ||
-        destTrimmedRect.right - destTrimmedRect.left < drawFramebuffer->getColorbuffer()->getWidth() ||
+    if (sourceTrimmedRect.bottom - sourceTrimmedRect.top < readBufferHeight ||
+        sourceTrimmedRect.right - sourceTrimmedRect.left < readBufferWidth || 
+        destTrimmedRect.bottom - destTrimmedRect.top < drawBufferHeight ||
+        destTrimmedRect.right - destTrimmedRect.left < drawBufferWidth ||
         sourceTrimmedRect.top != 0 || destTrimmedRect.top != 0 || sourceTrimmedRect.left != 0 || destTrimmedRect.left != 0)
     {
         partialBufferCopy = true;
@@ -3189,7 +3448,11 @@
 
     if (mask & GL_COLOR_BUFFER_BIT)
     {
-        if (readFramebuffer->getColorbufferType() != drawFramebuffer->getColorbufferType() ||
+        const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
+            readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
+        const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
+            drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
+        if (!validReadType || !validDrawType ||
             readFramebuffer->getColorbuffer()->getD3DFormat() != drawFramebuffer->getColorbuffer()->getD3DFormat())
         {
             ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h
index 6bca756..2906664 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h
@@ -12,6 +12,7 @@
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 #define EGLAPI
 #include <EGL/egl.h>
 #include <d3d9.h>
@@ -49,19 +50,20 @@
 class DepthStencilbuffer;
 class VertexDataManager;
 class IndexDataManager;
-class BufferBackEnd;
 class Blit;
+class Fence;
 
 enum
 {
-    MAX_VERTEX_ATTRIBS = 12,
-    MAX_VERTEX_UNIFORM_VECTORS = 128,
-    MAX_VARYING_VECTORS = 8,
+    MAX_VERTEX_ATTRIBS = 16,
+    MAX_VERTEX_UNIFORM_VECTORS = 256 - 2,   // 256 is the minimum for SM2, and in practice the maximum for DX9. Reserve space for dx_HalfPixelSize and dx_DepthRange.
+    MAX_VARYING_VECTORS_SM2 = 8,
+    MAX_VARYING_VECTORS_SM3 = 10,
     MAX_COMBINED_TEXTURE_IMAGE_UNITS = 16,
     MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0,
     MAX_TEXTURE_IMAGE_UNITS = 16,
-    MAX_FRAGMENT_UNIFORM_VECTORS = 16,
-    MAX_RENDERBUFFER_SIZE = 4096,   // FIXME: Verify
+    MAX_FRAGMENT_UNIFORM_VECTORS_SM2 = 32 - 3,    // Reserve space for dx_Viewport, dx_Depth, and dx_DepthRange. dx_PointOrLines and dx_FrontCCW use separate bool registers.
+    MAX_FRAGMENT_UNIFORM_VECTORS_SM3 = 224 - 3,
     MAX_DRAW_BUFFERS = 1,
 
     IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
@@ -83,32 +85,56 @@
 };
 
 // Helper structure describing a single vertex attribute
-class AttributeState
+class VertexAttribute
 {
   public:
-    AttributeState()
-        : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mEnabled(false)
+    VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)
     {
-        mCurrentValue[0] = 0;
-        mCurrentValue[1] = 0;
-        mCurrentValue[2] = 0;
-        mCurrentValue[3] = 1;
+        mCurrentValue[0] = 0.0f;
+        mCurrentValue[1] = 0.0f;
+        mCurrentValue[2] = 0.0f;
+        mCurrentValue[3] = 1.0f;
     }
 
-    // From VertexArrayPointer
+    int typeSize() const
+    {
+        switch (mType)
+        {
+          case GL_BYTE:           return mSize * sizeof(GLbyte);
+          case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);
+          case GL_SHORT:          return mSize * sizeof(GLshort);
+          case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
+          case GL_FIXED:          return mSize * sizeof(GLfixed);
+          case GL_FLOAT:          return mSize * sizeof(GLfloat);
+          default: UNREACHABLE(); return mSize * sizeof(GLfloat);
+        }
+    }
+
+    GLsizei stride() const
+    {
+        return mStride ? mStride : typeSize();
+    }
+
+    // From glVertexAttribPointer
     GLenum mType;
     GLint mSize;
     bool mNormalized;
-    GLsizei mStride; // 0 means natural stride
-    const void *mPointer;
+    GLsizei mStride;   // 0 means natural stride
 
-    BindingPointer<Buffer> mBoundBuffer; // Captured when VertexArrayPointer is called.
+    union
+    {
+        const void *mPointer;
+        intptr_t mOffset;
+    };
 
-    bool mEnabled; // From Enable/DisableVertexAttribArray
+    BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
 
-    float mCurrentValue[4]; // From VertexAttrib4f
+    bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
+    float mCurrentValue[4];   // From glVertexAttrib
 };
 
+typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
+
 // Helper structure to store all raw state
 struct State
 {
@@ -157,6 +183,7 @@
     GLfloat lineWidth;
 
     GLenum generateMipmapHint;
+    GLenum fragmentShaderDerivativeHint;
 
     GLint viewportX;
     GLint viewportY;
@@ -179,14 +206,12 @@
     int activeSampler;   // Active texture unit selector - GL_TEXTURE0
     BindingPointer<Buffer> arrayBuffer;
     BindingPointer<Buffer> elementArrayBuffer;
-    BindingPointer<Texture> texture2D;
-    BindingPointer<Texture> textureCubeMap;
     GLuint readFramebuffer;
     GLuint drawFramebuffer;
     BindingPointer<Renderbuffer> renderbuffer;
     GLuint currentProgram;
 
-    AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
+    VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
     BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
 
     GLint unpackAlignment;
@@ -264,6 +289,7 @@
     void setLineWidth(GLfloat width);
 
     void setGenerateMipmapHint(GLenum hint);
+    void setFragmentShaderDerivativeHint(GLenum hint);
 
     void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
 
@@ -280,13 +306,13 @@
 
     GLuint getArrayBufferHandle() const;
 
-    void setVertexAttribEnabled(unsigned int attribNum, bool enabled);
-    const AttributeState &getVertexAttribState(unsigned int attribNum);
+    void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
+    const VertexAttribute &getVertexAttribState(unsigned int attribNum);
     void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
                               bool normalized, GLsizei stride, const void *pointer);
     const void *getVertexAttribPointer(unsigned int attribNum) const;
 
-    const AttributeState *getVertexAttribBlock();
+    const VertexAttributeArray &getVertexAttributes();
 
     void setUnpackAlignment(GLint alignment);
     GLint getUnpackAlignment() const;
@@ -312,6 +338,10 @@
     GLuint createFramebuffer();
     void deleteFramebuffer(GLuint framebuffer);
 
+    // Fences are owned by the Context.
+    GLuint createFence();
+    void deleteFence(GLuint fence);
+
     void bindArrayBuffer(GLuint buffer);
     void bindElementArrayBuffer(GLuint buffer);
     void bindTexture2D(GLuint texture);
@@ -328,6 +358,7 @@
     void setVertexAttrib(GLuint index, const GLfloat *values);
 
     Buffer *getBuffer(GLuint handle);
+    Fence *getFence(GLuint handle);
     Shader *getShader(GLuint handle);
     Program *getProgram(GLuint handle);
     Texture *getTexture(GLuint handle);
@@ -351,20 +382,22 @@
 
     bool applyRenderTarget(bool ignoreViewport);
     void applyState(GLenum drawMode);
-    GLenum applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool *useIndexing, TranslatedIndexData *indexInfo);
-    GLenum applyVertexBuffer(const TranslatedIndexData &indexInfo);
+    GLenum applyVertexBuffer(GLint first, GLsizei count);
     GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
-    GLenum applyCountingIndexBuffer(GLenum mode, GLenum count, TranslatedIndexData *indexInfo);
     void applyShaders();
     void applyTextures();
 
     void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
     void clear(GLbitfield mask);
     void drawArrays(GLenum mode, GLint first, GLsizei count);
-    void drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
+    void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
     void finish();
     void flush();
 
+	// Draw the last segment of a line loop
+    void drawClosingLine(unsigned int first, unsigned int last);
+    void drawClosingLine(GLsizei count, GLenum type, const void *indices);
+
     void recordInvalidEnum();
     void recordInvalidValue();
     void recordInvalidOperation();
@@ -374,10 +407,26 @@
     GLenum getError();
 
     bool supportsShaderModel3() const;
+    int getMaximumVaryingVectors() const;
+    int getMaximumFragmentUniformVectors() const;
+    int getMaximumRenderbufferDimension() const;
+    int getMaximumTextureDimension() const;
+    int getMaximumCubeTextureDimension() const;
+    int getMaximumTextureLevel() const;
     GLsizei getMaxSupportedSamples() const;
     int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
     const char *getExtensionString() const;
+    bool supportsEventQueries() const;
     bool supportsCompressedTextures() const;
+    bool supportsFloatTextures() const;
+    bool supportsFloatLinearFilter() const;
+    bool supportsFloatRenderableTextures() const;
+    bool supportsHalfFloatTextures() const;
+    bool supportsHalfFloatLinearFilter() const;
+    bool supportsHalfFloatRenderableTextures() const;
+    bool supportsLuminanceTextures() const;
+    bool supportsLuminanceAlphaTextures() const;
+    bool supports32bitIndices() const;
 
     void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 
                          GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
@@ -406,25 +455,24 @@
 
     State   mState;
 
-    Texture2D *mTexture2DZero;
-    TextureCubeMap *mTextureCubeMapZero;
-
-    Colorbuffer *mColorbufferZero;
-    DepthStencilbuffer *mDepthStencilbufferZero;
+    BindingPointer<Texture2D> mTexture2DZero;
+    BindingPointer<TextureCubeMap> mTextureCubeMapZero;
 
     typedef std::map<GLuint, Framebuffer*> FramebufferMap;
     FramebufferMap mFramebufferMap;
 
+    typedef std::map<GLuint, Fence*> FenceMap;
+    FenceMap mFenceMap;
+
     void initExtensionString();
     std::string mExtensionString;
 
-    BufferBackEnd *mBufferBackEnd;
     VertexDataManager *mVertexDataManager;
     IndexDataManager *mIndexDataManager;
 
     Blit *mBlit;
     
-    Texture *mIncompleteTextures[SAMPLER_TYPE_COUNT];
+    BindingPointer<Texture> mIncompleteTextures[SAMPLER_TYPE_COUNT];
 
     // Recorded errors
     bool mInvalidEnum;
@@ -439,11 +487,26 @@
     unsigned int mAppliedRenderTargetSerial;
     unsigned int mAppliedDepthbufferSerial;
     unsigned int mAppliedStencilbufferSerial;
+    bool mDepthStencilInitialized;
 
     bool mSupportsShaderModel3;
+    int  mMaxRenderbufferDimension;
+    int  mMaxTextureDimension;
+    int  mMaxCubeTextureDimension;
+    int  mMaxTextureLevel;
     std::map<D3DFORMAT, bool *> mMultiSampleSupport;
     GLsizei mMaxSupportedSamples;
+    bool mSupportsEventQueries;
     bool mSupportsCompressedTextures;
+    bool mSupportsFloatTextures;
+    bool mSupportsFloatLinearFilter;
+    bool mSupportsFloatRenderableTextures;
+    bool mSupportsHalfFloatTextures;
+    bool mSupportsHalfFloatLinearFilter;
+    bool mSupportsHalfFloatRenderableTextures;
+    bool mSupportsLuminanceTextures;
+    bool mSupportsLuminanceAlphaTextures;
+    bool mSupports32bitIndices;
 
     // state caching flags
     bool mClearStateDirty;
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp
new file mode 100644
index 0000000..7fbcb6a
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp
@@ -0,0 +1,134 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
+
+#include "libGLESv2/Fence.h"
+
+#include "libGLESv2/main.h"
+
+namespace gl
+{
+
+Fence::Fence()
+{ 
+    mQuery = NULL;
+    mCondition = GL_NONE;
+    mStatus = GL_FALSE;
+}
+
+Fence::~Fence()
+{
+    if (mQuery != NULL)
+    {
+        mQuery->Release();
+        mQuery = NULL;
+    }
+}
+
+GLboolean Fence::isFence()
+{
+    // GL_NV_fence spec:
+    // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
+    return mQuery != NULL;
+}
+
+void Fence::setFence(GLenum condition)
+{
+    if (mQuery != NULL)
+    {
+        mQuery->Release();
+        mQuery = NULL;
+    }
+
+    if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery)))
+    {
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    HRESULT result = mQuery->Issue(D3DISSUE_END);
+    ASSERT(SUCCEEDED(result));
+
+    mCondition = condition;
+    mStatus = GL_FALSE;
+}
+
+GLboolean Fence::testFence()
+{
+    if (mQuery == NULL)
+    {
+        return error(GL_INVALID_OPERATION, GL_TRUE);
+    }
+
+    HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+    if (result == D3DERR_DEVICELOST)
+    {
+       return error(GL_OUT_OF_MEMORY, GL_TRUE);
+    }
+
+    ASSERT(result == S_OK || result == S_FALSE);
+    mStatus = result == S_OK;
+    return mStatus;
+}
+
+void Fence::finishFence()
+{
+    if (mQuery == NULL)
+    {
+        return error(GL_INVALID_OPERATION);
+    }
+
+    while (!testFence())
+    {
+        Sleep(0);
+    }
+}
+
+void Fence::getFenceiv(GLenum pname, GLint *params)
+{
+    if (mQuery == NULL)
+    {
+        return error(GL_INVALID_OPERATION);
+    }
+
+    switch (pname)
+    {
+        case GL_FENCE_STATUS_NV:
+        {
+            // GL_NV_fence spec:
+            // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
+            // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
+            if (mStatus)
+            {
+                params[0] = GL_TRUE;
+                return;
+            }
+            
+            HRESULT result = mQuery->GetData(NULL, 0, 0);
+            
+            if (result == D3DERR_DEVICELOST)
+            {
+                params[0] = GL_TRUE;
+                return error(GL_OUT_OF_MEMORY);
+            }
+
+            ASSERT(result == S_OK || result == S_FALSE);
+            mStatus = result == S_OK;
+            params[0] = mStatus;
+            
+            break;
+        }
+        case GL_FENCE_CONDITION_NV:
+            params[0] = mCondition;
+            break;
+        default:
+            return error(GL_INVALID_ENUM);
+            break;
+    }
+}
+
+}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h
new file mode 100644
index 0000000..17bad78
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension.
+
+#ifndef LIBGLESV2_FENCE_H_
+#define LIBGLESV2_FENCE_H_
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+#include <d3d9.h>
+
+#include "common/angleutils.h"
+
+namespace gl
+{
+
+class Fence
+{
+  public:
+    Fence();
+    virtual ~Fence();
+
+    GLboolean isFence();
+    void setFence(GLenum condition);
+    GLboolean testFence();
+    void finishFence();
+    void getFenceiv(GLenum pname, GLint *params);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Fence);
+
+    IDirect3DQuery9* mQuery;
+    GLenum mCondition;
+    GLboolean mStatus;
+};
+
+}
+
+#endif   // LIBGLESV2_FENCE_H_
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp
index 5c4bc99..5fe01e0 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp
@@ -305,13 +305,32 @@
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        if (IsTextureTarget(mColorbufferType))
+        if (mColorbufferType == GL_RENDERBUFFER)
+        {
+            if (!gl::IsColorRenderable(colorbuffer->getFormat()))
+            {
+                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+            }
+        }
+        else if (IsTextureTarget(mColorbufferType))
         {
             if (IsCompressed(colorbuffer->getFormat()))
             {
                 return GL_FRAMEBUFFER_UNSUPPORTED;
             }
+
+            if (colorbuffer->isFloatingPoint() && (!getContext()->supportsFloatRenderableTextures() || 
+                                                   !getContext()->supportsHalfFloatRenderableTextures()))
+            {
+                return GL_FRAMEBUFFER_UNSUPPORTED;
+            }
+
+            if (colorbuffer->getFormat() == GL_LUMINANCE || colorbuffer->getFormat() == GL_LUMINANCE_ALPHA)
+            {
+                return GL_FRAMEBUFFER_UNSUPPORTED;
+            }
         }
+        else UNREACHABLE();
 
         width = colorbuffer->getWidth();
         height = colorbuffer->getHeight();
@@ -327,6 +346,11 @@
 
     if (mDepthbufferType != GL_NONE)
     {
+        if (mDepthbufferType != GL_RENDERBUFFER)
+        {
+            return GL_FRAMEBUFFER_UNSUPPORTED;   // Requires GL_OES_depth_texture
+        }
+
         depthbuffer = getDepthbuffer();
 
         if (!depthbuffer)
@@ -357,18 +381,15 @@
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
-        
-        if (IsTextureTarget(mDepthbufferType))
-        {
-            if (IsCompressed(depthbuffer->getFormat()))
-            {
-                return GL_FRAMEBUFFER_UNSUPPORTED;
-            }
-        }
     }
 
     if (mStencilbufferType != GL_NONE)
     {
+        if (mStencilbufferType != GL_RENDERBUFFER)
+        {
+            return GL_FRAMEBUFFER_UNSUPPORTED;
+        }
+
         stencilbuffer = getStencilbuffer();
 
         if (!stencilbuffer)
@@ -399,14 +420,6 @@
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
-        
-        if (IsTextureTarget(mStencilbufferType))
-        {
-            if (IsCompressed(stencilbuffer->getFormat()))
-            {
-                return GL_FRAMEBUFFER_UNSUPPORTED;
-            }
-        }
     }
 
     if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
@@ -425,8 +438,8 @@
 DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil)
 {
     mColorbufferType = GL_RENDERBUFFER;
-    mDepthbufferType = GL_RENDERBUFFER;
-    mStencilbufferType = GL_RENDERBUFFER;
+    mDepthbufferType = (depthStencil->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
+    mStencilbufferType = (depthStencil->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
 
     mColorbufferPointer.set(new Renderbuffer(0, color));
 
@@ -449,6 +462,9 @@
 
 GLenum DefaultFramebuffer::completeness()
 {
+    // The default framebuffer should always be complete
+    ASSERT(Framebuffer::completeness() == GL_FRAMEBUFFER_COMPLETE);
+
     return GL_FRAMEBUFFER_COMPLETE;
 }
 
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp
index a32bc9f..780c3e3 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp
@@ -45,7 +45,7 @@
 {
 }
 
-Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
+Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial())
 {
     mFragmentShader = NULL;
     mVertexShader = NULL;
@@ -63,8 +63,6 @@
     mDeleteStatus = false;
 
     mRefCount = 0;
-
-    mSerial = issueSerial();
 }
 
 Program::~Program()
@@ -205,7 +203,7 @@
         logicalTextureUnit = mSamplers[samplerIndex].logicalTextureUnit;
     }
 
-    if (logicalTextureUnit < MAX_TEXTURE_IMAGE_UNITS)
+    if (logicalTextureUnit >= 0 && logicalTextureUnit < MAX_TEXTURE_IMAGE_UNITS)
     {
         return logicalTextureUnit;
     }
@@ -243,26 +241,22 @@
 
 GLint Program::getUniformLocation(const char *name, bool decorated)
 {
-    std::string nameStr(name);
+    std::string _name = decorated ? name : decorate(name);
     int subscript = 0;
-    size_t beginB = nameStr.find('[');
-    size_t endB = nameStr.find(']');
-    if (beginB != std::string::npos && endB != std::string::npos)
-    {
-        std::string subscrStr = nameStr.substr(beginB + 1, beginB - endB - 1);
-        nameStr.erase(beginB);
-        subscript = atoi(subscrStr.c_str());
-    }
 
-    if (!decorated)
+    // Strip any trailing array operator and retrieve the subscript
+    size_t open = _name.find_last_of('[');
+    size_t close = _name.find_last_of(']');
+    if (open != std::string::npos && close == _name.length() - 1)
     {
-        nameStr = decorate(nameStr);
+        subscript = atoi(_name.substr(open + 1).c_str());
+        _name.erase(open);
     }
 
     unsigned int numUniforms = mUniformIndex.size();
     for (unsigned int location = 0; location < numUniforms; location++)
     {
-        if (mUniformIndex[location].name == nameStr &&
+        if (mUniformIndex[location].name == _name &&
             mUniformIndex[location].element == subscript)
         {
             return location;
@@ -595,7 +589,9 @@
     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
     targetUniform->dirty = true;
 
-    if (targetUniform->type == GL_INT)
+    if (targetUniform->type == GL_INT ||
+        targetUniform->type == GL_SAMPLER_2D ||
+        targetUniform->type == GL_SAMPLER_CUBE)
     {
         int arraySize = targetUniform->arraySize;
 
@@ -949,6 +945,8 @@
               case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, arraySize, f); break;
               case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, arraySize, f); break;
               case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, arraySize, f); break;
+              case GL_SAMPLER_2D:
+              case GL_SAMPLER_CUBE:
               case GL_INT:        applyUniform1iv(location, arraySize, i);       break;
               case GL_INT_VEC2:   applyUniform2iv(location, arraySize, i);       break;
               case GL_INT_VEC3:   applyUniform3iv(location, arraySize, i);       break;
@@ -1001,6 +999,9 @@
 // Returns the number of used varying registers, or -1 if unsuccesful
 int Program::packVaryings(const Varying *packing[][4])
 {
+    Context *context = getContext();
+    const int maxVaryingVectors = context->getMaximumVaryingVectors();
+
     for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++)
     {
         int n = VariableRowCount(varying->type) * varying->size;
@@ -1009,7 +1010,7 @@
 
         if (m == 2 || m == 3 || m == 4)
         {
-            for (int r = 0; r <= MAX_VARYING_VECTORS - n && !success; r++)
+            for (int r = 0; r <= maxVaryingVectors - n && !success; r++)
             {
                 bool available = true;
 
@@ -1043,7 +1044,7 @@
 
             if (!success && m == 2)
             {
-                for (int r = MAX_VARYING_VECTORS - n; r >= 0 && !success; r--)
+                for (int r = maxVaryingVectors - n; r >= 0 && !success; r--)
                 {
                     bool available = true;
 
@@ -1080,7 +1081,7 @@
         {
             int space[4] = {0};
 
-            for (int y = 0; y < MAX_VARYING_VECTORS; y++)
+            for (int y = 0; y < maxVaryingVectors; y++)
             {
                 for (int x = 0; x < 4; x++)
                 {
@@ -1100,7 +1101,7 @@
 
             if (space[column] > n)
             {
-                for (int r = 0; r < MAX_VARYING_VECTORS; r++)
+                for (int r = 0; r < maxVaryingVectors; r++)
                 {
                     if (!packing[r][column])
                     {
@@ -1133,7 +1134,7 @@
     // Return the number of used registers
     int registers = 0;
 
-    for (int r = 0; r < MAX_VARYING_VECTORS; r++)
+    for (int r = 0; r < maxVaryingVectors; r++)
     {
         if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
         {
@@ -1151,7 +1152,7 @@
         return false;
     }
 
-    const Varying *packing[MAX_VARYING_VECTORS][4] = {NULL};
+    const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL};
     int registers = packVaryings(packing);
 
     if (registers < 0)
@@ -1159,7 +1160,11 @@
         return false;
     }
 
-    if (registers == MAX_VARYING_VECTORS && mFragmentShader->mUsesFragCoord)
+    Context *context = getContext();
+    const bool sm3 = context->supportsShaderModel3();
+    const int maxVaryingVectors = context->getMaximumVaryingVectors();
+
+    if (registers == maxVaryingVectors && mFragmentShader->mUsesFragCoord)
     {
         appendToInfoLog("No varying registers left to support gl_FragCoord");
 
@@ -1197,8 +1202,6 @@
         }
     }
 
-    Context *context = getContext();
-    bool sm3 = context->supportsShaderModel3();
     std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD");
 
     mVertexHLSL += "struct VS_INPUT\n"
@@ -1371,6 +1374,9 @@
     if (mFragmentShader->mUsesFragCoord)
     {
         mPixelHLSL += "    float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+        if (sm3) {
+            mPixelHLSL += "    float2 dx_VPos : VPOS;\n";
+        }
     }
 
     if (mFragmentShader->mUsesPointCoord && sm3)
@@ -1395,10 +1401,15 @@
 
     if (mFragmentShader->mUsesFragCoord)
     {
-        mPixelHLSL += "    float rhw = 1.0 / input.gl_FragCoord.w;\n"
-                      "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n"
-                      "    gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n"
-                      "    gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
+        mPixelHLSL += "    float rhw = 1.0 / input.gl_FragCoord.w;\n";
+        if (sm3) {
+            mPixelHLSL += "    gl_FragCoord.x = input.dx_VPos.x;\n"
+                          "    gl_FragCoord.y = input.dx_VPos.y;\n";
+        } else {
+            mPixelHLSL += "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n"
+                          "    gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n";
+        }
+        mPixelHLSL += "    gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
                       "    gl_FragCoord.w = rhw;\n";
     }
 
@@ -1525,9 +1536,7 @@
 
             // these uniforms are searched as already-decorated because gl_ and dx_
             // are reserved prefixes, and do not receive additional decoration
-            mDepthRangeNearLocation = getUniformLocation("gl_DepthRange.near", true);
-            mDepthRangeFarLocation = getUniformLocation("gl_DepthRange.far", true);
-            mDepthRangeDiffLocation = getUniformLocation("gl_DepthRange.diff", true);
+            mDxDepthRangeLocation = getUniformLocation("dx_DepthRange", true);
             mDxDepthLocation = getUniformLocation("dx_Depth", true);
             mDxViewportLocation = getUniformLocation("dx_Viewport", true);
             mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize", true);
@@ -1650,32 +1659,38 @@
 {
     if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
     {
-        unsigned int samplerIndex = constantDescription.RegisterIndex;
+        for (unsigned int samplerIndex = constantDescription.RegisterIndex; samplerIndex < constantDescription.RegisterIndex + constantDescription.RegisterCount; samplerIndex++)
+        {
+            ASSERT(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
 
-        assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
-
-        mSamplers[samplerIndex].active = true;
-        mSamplers[samplerIndex].type = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? SAMPLER_CUBE : SAMPLER_2D;
-        mSamplers[samplerIndex].logicalTextureUnit = 0;
-        mSamplers[samplerIndex].dirty = true;
+            mSamplers[samplerIndex].active = true;
+            mSamplers[samplerIndex].type = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? SAMPLER_CUBE : SAMPLER_2D;
+            mSamplers[samplerIndex].logicalTextureUnit = 0;
+            mSamplers[samplerIndex].dirty = true;
+        }
     }
 
     switch(constantDescription.Class)
     {
       case D3DXPC_STRUCT:
         {
-            for (unsigned int field = 0; field < constantDescription.StructMembers; field++)
+            for (unsigned int arrayIndex = 0; arrayIndex < constantDescription.Elements; arrayIndex++)
             {
-                D3DXHANDLE fieldHandle = mConstantTablePS->GetConstant(constantHandle, field);
-
-                D3DXCONSTANT_DESC fieldDescription;
-                UINT descriptionCount = 1;
-
-                mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount);
-
-                if (!defineUniform(fieldHandle, fieldDescription, name + constantDescription.Name + "."))
+                for (unsigned int field = 0; field < constantDescription.StructMembers; field++)
                 {
-                    return false;
+                    D3DXHANDLE fieldHandle = mConstantTablePS->GetConstant(constantHandle, field);
+
+                    D3DXCONSTANT_DESC fieldDescription;
+                    UINT descriptionCount = 1;
+
+                    mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount);
+
+                    std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : "";
+
+                    if (!defineUniform(fieldHandle, fieldDescription, name + constantDescription.Name + structIndex + "."))
+                    {
+                        return false;
+                    }
                 }
             }
 
@@ -1737,10 +1752,16 @@
         switch (constantDescription.Type)
         {
           case D3DXPT_SAMPLER2D:
+            switch (constantDescription.Columns)
+            {
+              case 1: return new Uniform(GL_SAMPLER_2D, name, constantDescription.Elements);
+              default: UNREACHABLE();
+            }
+            break;
           case D3DXPT_SAMPLERCUBE:
             switch (constantDescription.Columns)
             {
-              case 1: return new Uniform(GL_INT, name, constantDescription.Elements);
+              case 1: return new Uniform(GL_SAMPLER_CUBE, name, constantDescription.Elements);
               default: UNREACHABLE();
             }
             break;
@@ -2205,14 +2226,14 @@
         {
             unsigned int firstIndex = mConstantTablePS->GetSamplerIndex(constantPS);
 
-            for (unsigned int samplerIndex = firstIndex; samplerIndex < firstIndex + count; samplerIndex++)
+            for (int i = 0; i < count; i++)
             {
-                GLint mappedSampler = v[0];
+                unsigned int samplerIndex = firstIndex + i;
 
-                if (samplerIndex >= 0 && samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+                if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
                 {
                     ASSERT(mSamplers[samplerIndex].active);
-                    mSamplers[samplerIndex].logicalTextureUnit = mappedSampler;
+                    mSamplers[samplerIndex].logicalTextureUnit = v[i];
                     mSamplers[samplerIndex].dirty = true;
                 }
             }
@@ -2371,6 +2392,7 @@
     if (mInfoLog)
     {
         delete [] mInfoLog;
+        mInfoLog = NULL;
     }
 }
 
@@ -2434,9 +2456,7 @@
         mUniforms.pop_back();
     }
 
-    mDepthRangeDiffLocation = -1;
-    mDepthRangeNearLocation = -1;
-    mDepthRangeFarLocation = -1;
+    mDxDepthRangeLocation = -1;
     mDxDepthLocation = -1;
     mDxViewportLocation = -1;
     mDxHalfPixelSizeLocation = -1;
@@ -2562,16 +2582,22 @@
 
 void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
 {
-    unsigned int attribute = 0;
-    for (unsigned int i = 0; i < index; i++)
+    // Skip over inactive attributes
+    unsigned int activeAttribute = 0;
+    unsigned int attribute;
+    for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
     {
-        do
+        if (mLinkedAttribute[attribute].name.empty())
         {
-            attribute++;
-
-            ASSERT(attribute < MAX_VERTEX_ATTRIBS);   // index must be smaller than getActiveAttributeCount()
+            continue;
         }
-        while (mLinkedAttribute[attribute].name.empty());
+
+        if (activeAttribute == index)
+        {
+            break;
+        }
+
+        activeAttribute++;
     }
 
     if (bufsize > 0)
@@ -2624,18 +2650,26 @@
 
 void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
 {
-    unsigned int uniform = 0;
-    for (unsigned int i = 0; i < index; i++)
+    // Skip over internal uniforms
+    unsigned int activeUniform = 0;
+    unsigned int uniform;
+    for (uniform = 0; uniform < mUniforms.size(); uniform++)
     {
-        do
+        if (mUniforms[uniform]->name.substr(0, 3) == "dx_")
         {
-            uniform++;
-
-            ASSERT(uniform < mUniforms.size());   // index must be smaller than getActiveUniformCount()
+            continue;
         }
-        while (mUniforms[uniform]->name.substr(0, 3) == "dx_");
+
+        if (activeUniform == index)
+        {
+            break;
+        }
+
+        activeUniform++;
     }
 
+    ASSERT(uniform < mUniforms.size());   // index must be smaller than getActiveUniformCount()
+
     if (bufsize > 0)
     {
         std::string string = undecorate(mUniforms[uniform]->name);
@@ -2763,19 +2797,9 @@
     *constantVS = targetUniform->vsHandle;
 }
 
-GLint Program::getDepthRangeDiffLocation() const
+GLint Program::getDxDepthRangeLocation() const
 {
-    return mDepthRangeDiffLocation;
-}
-
-GLint Program::getDepthRangeNearLocation() const
-{
-    return mDepthRangeNearLocation;
-}
-
-GLint Program::getDepthRangeFarLocation() const
-{
-    return mDepthRangeFarLocation;
+    return mDxDepthRangeLocation;
 }
 
 GLint Program::getDxDepthLocation() const
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h
index 3021b7a..e9c149e 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h
@@ -94,9 +94,7 @@
     bool getUniformfv(GLint location, GLfloat *params);
     bool getUniformiv(GLint location, GLint *params);
 
-    GLint getDepthRangeDiffLocation() const;
-    GLint getDepthRangeNearLocation() const;
-    GLint getDepthRangeFarLocation() const;
+    GLint getDxDepthRangeLocation() const;
     GLint getDxDepthLocation() const;
     GLint getDxViewportLocation() const;
     GLint getDxHalfPixelSizeLocation() const;
@@ -204,9 +202,7 @@
     typedef std::vector<UniformLocation> UniformIndex;
     UniformIndex mUniformIndex;
 
-    GLint mDepthRangeDiffLocation;
-    GLint mDepthRangeNearLocation;
-    GLint mDepthRangeFarLocation;
+    GLint mDxDepthRangeLocation;
     GLint mDxDepthLocation;
     GLint mDxViewportLocation;
     GLint mDxHalfPixelSizeLocation;
@@ -220,7 +216,7 @@
 
     unsigned int mRefCount;
 
-    unsigned int mSerial;
+    const unsigned int mSerial;
 
     static unsigned int mCurrentSerial;
 
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp
index e3fd36e..2de1e71 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp
@@ -22,6 +22,7 @@
 
 RefCountObject::~RefCountObject()
 {
+    ASSERT(mRefCount == 0);
 }
 
 void RefCountObject::addRef() const
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp
index 0eb4637..6e4494b 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp
@@ -11,6 +11,7 @@
 #include "libGLESv2/Renderbuffer.h"
 
 #include "libGLESv2/main.h"
+#include "libGLESv2/Texture.h"
 #include "libGLESv2/utilities.h"
 
 namespace gl
@@ -86,9 +87,13 @@
     mStorage = newStorage;
 }
 
-RenderbufferStorage::RenderbufferStorage()
+RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial())
 {
-    mSerial = issueSerial();
+    mWidth = 0;
+    mHeight = 0;
+    mFormat = GL_RGBA4;
+    mD3DFormat = D3DFMT_A8R8G8B8;
+    mSamples = 0;
 }
 
 RenderbufferStorage::~RenderbufferStorage()
@@ -141,6 +146,11 @@
     return mFormat;
 }
 
+bool RenderbufferStorage::isFloatingPoint() const
+{
+    return false; // no floating point renderbuffers 
+}
+
 D3DFORMAT RenderbufferStorage::getD3DFormat() const
 {
     return mD3DFormat;
@@ -171,14 +181,17 @@
         renderTarget->GetDesc(&description);
 
         setSize(description.Width, description.Height);
+        mFormat = dx2es::ConvertBackBufferFormat(description.Format);
         mD3DFormat = description.Format;
         mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
     }
-    else
-    {
-        mD3DFormat = D3DFMT_UNKNOWN;
-        mSamples = 0;
-    }
+}
+
+Colorbuffer::Colorbuffer(const Texture* texture) : mRenderTarget(NULL)
+{
+    setSize(texture->getWidth(), texture->getHeight());
+    mD3DFormat = texture->getD3DFormat();
+    mSamples = 0;
 }
 
 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
@@ -218,13 +231,6 @@
         mD3DFormat = requestedFormat;
         mSamples = supportedSamples;
     }
-    else
-    {
-        setSize(0, 0);
-        mFormat = GL_RGBA4;
-        mD3DFormat = D3DFMT_UNKNOWN;
-        mSamples = 0;
-    }
 }
 
 Colorbuffer::~Colorbuffer()
@@ -307,15 +313,10 @@
         depthStencil->GetDesc(&description);
 
         setSize(description.Width, description.Height);
-        mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
+        mFormat = dx2es::ConvertDepthStencilFormat(description.Format);
         mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType); 
         mD3DFormat = description.Format;
     }
-    else
-    {
-        mD3DFormat = D3DFMT_UNKNOWN; 
-        mSamples = 0;
-    }
 }
 
 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
@@ -352,13 +353,6 @@
         mD3DFormat = D3DFMT_D24S8;
         mSamples = supportedSamples;
     }
-    else
-    {
-        setSize(0, 0);
-        mFormat = GL_RGBA4; //default format
-        mD3DFormat = D3DFMT_UNKNOWN;
-        mSamples = 0;
-    }
 }
 
 DepthStencilbuffer::~DepthStencilbuffer()
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h
index cb8c06a..98510c2 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h
@@ -21,6 +21,7 @@
 
 namespace gl
 {
+    class Texture;
 
 // A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
 // is called. The specific concrete type depends on whether the internal format is
@@ -42,6 +43,7 @@
     virtual int getWidth() const;
     virtual int getHeight() const;
     virtual GLenum getFormat() const;
+    virtual bool isFloatingPoint() const;
     D3DFORMAT getD3DFormat() const;
     GLsizei getSamples() const;
     unsigned int getSerial() const;
@@ -53,7 +55,7 @@
     GLenum mFormat;
     D3DFORMAT mD3DFormat;
     GLsizei mSamples;
-    unsigned int mSerial;
+    const unsigned int mSerial;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
@@ -100,6 +102,7 @@
 {
   public:
     explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
+    explicit Colorbuffer(const Texture* texture);
     Colorbuffer(int width, int height, GLenum format, GLsizei samples);
 
     ~Colorbuffer();
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp
index b73ef2a..4c969d6 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp
@@ -34,19 +34,22 @@
 
         if (result)
         {
-            TBuiltInResource resources;
-            ShInitBuiltInResource(&resources);
+            ShBuiltInResources resources;
+            ShInitBuiltInResources(&resources);
+            Context *context = getContext();            
+
             resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
             resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
-            resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
+            resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
             resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
             resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
             resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
-            resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
+            resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
             resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
+            resources.OES_standard_derivatives = 1;
 
-            mFragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2, &resources);
-            mVertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2, &resources);
+            mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources);
+            mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources);
         }
     }
 
@@ -240,7 +243,7 @@
             char varyingType[256];
             char varyingName[256];
 
-            int matches = sscanf(input, "static %s %s", varyingType, varyingName);
+            int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
 
             if (matches != 2)
             {
@@ -280,21 +283,23 @@
     delete[] mInfoLog;
     mInfoLog = NULL;
 
-    int result = ShCompile(compiler, &mSource, 1, EShOptNone, EDebugOpNone);
-    const char *obj = ShGetObjectCode(compiler);
-    const char *info = ShGetInfoLog(compiler);
+    int result = ShCompile(compiler, &mSource, 1, SH_OBJECT_CODE);
 
     if (result)
     {
-        mHlsl = new char[strlen(obj) + 1];
-        strcpy(mHlsl, obj);
+        int objCodeLen = 0;
+        ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
+        mHlsl = new char[objCodeLen];
+        ShGetObjectCode(compiler, mHlsl);
 
         TRACE("\n%s", mHlsl);
     }
     else
     {
-        mInfoLog = new char[strlen(info) + 1];
-        strcpy(mInfoLog, info);
+        int infoLogLen = 0;
+        ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
+        mInfoLog = new char[infoLogLen];
+        ShGetInfoLog(compiler, mInfoLog);
 
         TRACE("\n%s", mInfoLog);
     }
@@ -468,7 +473,7 @@
             char attributeType[256];
             char attributeName[256];
 
-            int matches = sscanf(input, "static %s _%s", attributeType, attributeName);
+            int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
 
             if (matches != 2)
             {
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp
index 2e0b1e3..7c040f8 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp
@@ -10,6 +10,8 @@
 
 #include "libGLESv2/Texture.h"
 
+#include <d3dx9tex.h>
+
 #include <algorithm>
 
 #include "common/debug.h"
@@ -45,6 +47,7 @@
     mDirtyMetaData = true;
     mDirty = true;
     mIsRenderable = false;
+    mType = GL_UNSIGNED_BYTE;
     mBaseTexture = NULL;
 }
 
@@ -174,86 +177,171 @@
     return mHeight;
 }
 
+bool Texture::isFloatingPoint() const
+{
+    return (mType == GL_FLOAT || mType == GL_HALF_FLOAT_OES);
+}
+
+bool Texture::isRenderableFormat() const
+{
+    D3DFORMAT format = getD3DFormat();
+    
+    switch(format)
+    {
+      case D3DFMT_L8:
+      case D3DFMT_A8L8:
+      case D3DFMT_DXT1:
+        return false;
+      case D3DFMT_A8R8G8B8:
+      case D3DFMT_X8R8G8B8:
+      case D3DFMT_A16B16G16R16F:
+      case D3DFMT_A32B32G32R32F:
+        return true;
+      default:
+        UNREACHABLE();
+    }
+
+    return false;
+}
+
 // Selects an internal Direct3D 9 format for storing an Image
-D3DFORMAT Texture::selectFormat(GLenum format)
+D3DFORMAT Texture::selectFormat(GLenum format, GLenum type)
 {
     if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
         format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
     {
         return D3DFMT_DXT1;
     }
-    else
+    else if (type == GL_FLOAT)
     {
+        return D3DFMT_A32B32G32R32F;
+    }
+    else if (type == GL_HALF_FLOAT_OES)
+    {
+        return D3DFMT_A16B16G16R16F;
+    }
+    else if (type == GL_UNSIGNED_BYTE)
+    {
+        if (format == GL_LUMINANCE && getContext()->supportsLuminanceTextures())
+        {
+            return D3DFMT_L8;
+        }
+        else if (format == GL_LUMINANCE_ALPHA && getContext()->supportsLuminanceAlphaTextures())
+        {
+            return D3DFMT_A8L8;
+        }
+        else if (format == GL_RGB)
+        {
+            return D3DFMT_X8R8G8B8;
+        }
+
         return D3DFMT_A8R8G8B8;
     }
-}
 
-int Texture::imagePitch(const Image &img) const
-{
-    return img.width * 4;
+    return D3DFMT_A8R8G8B8;
 }
 
 // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
-// into the BGRA8 pixel rectangle at output with outputPitch bytes in between each line.
+// into the target pixel rectangle at output with outputPitch bytes in between each line.
 void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
-                            GLint unpackAlignment, const void *input, size_t outputPitch, void *output) const
+                            GLint unpackAlignment, const void *input, size_t outputPitch, void *output, D3DSURFACE_DESC *description) const
 {
     GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
 
-    switch (format)
+    switch (type)
     {
-      case GL_ALPHA:
-        loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
-        break;
-
-      case GL_LUMINANCE:
-        loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
-        break;
-
-      case GL_LUMINANCE_ALPHA:
-        loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
-        break;
-
-      case GL_RGB:
-        switch (type)
+      case GL_UNSIGNED_BYTE:
+        switch (format)
         {
-          case GL_UNSIGNED_BYTE:
+          case GL_ALPHA:
+            loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_LUMINANCE:
+            loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, description->Format == D3DFMT_L8);
+            break;
+          case GL_LUMINANCE_ALPHA:
+            loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, description->Format == D3DFMT_A8L8);
+            break;
+          case GL_RGB:
             loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
             break;
-
-          case GL_UNSIGNED_SHORT_5_6_5:
-            loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
-            break;
-
-          default: UNREACHABLE();
-        }
-        break;
-
-      case GL_RGBA:
-        switch (type)
-        {
-          case GL_UNSIGNED_BYTE:
+          case GL_RGBA:
             loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
             break;
-
-          case GL_UNSIGNED_SHORT_4_4_4_4:
-            loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+          case GL_BGRA_EXT:
+            loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
             break;
-
-          case GL_UNSIGNED_SHORT_5_5_5_1:
-            loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
-            break;
-
           default: UNREACHABLE();
         }
         break;
-      case GL_BGRA_EXT:
-        switch (type)
+      case GL_UNSIGNED_SHORT_5_6_5:
+        switch (format)
         {
-          case GL_UNSIGNED_BYTE:
-            loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+          case GL_RGB:
+            loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
             break;
-
+          default: UNREACHABLE();
+        }
+        break;
+      case GL_UNSIGNED_SHORT_4_4_4_4:
+        switch (format)
+        {
+          case GL_RGBA:
+            loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          default: UNREACHABLE();
+        }
+        break;
+      case GL_UNSIGNED_SHORT_5_5_5_1:
+        switch (format)
+        {
+          case GL_RGBA:
+            loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          default: UNREACHABLE();
+        }
+        break;
+      case GL_FLOAT:
+        switch (format)
+        {
+          // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
+          case GL_ALPHA:
+            loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_LUMINANCE:
+            loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_LUMINANCE_ALPHA:
+            loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_RGB:
+            loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_RGBA:
+            loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          default: UNREACHABLE();
+        }
+        break;
+      case GL_HALF_FLOAT_OES:
+        switch (format)
+        {
+          // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
+          case GL_ALPHA:
+            loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_LUMINANCE:
+            loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_LUMINANCE_ALPHA:
+            loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_RGB:
+            loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
+          case GL_RGBA:
+            loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+            break;
           default: UNREACHABLE();
         }
         break;
@@ -281,36 +369,174 @@
     }
 }
 
-void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
-                                     size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+void Texture::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                      size_t inputPitch, const void *input, size_t outputPitch, void *output) const
 {
+    const float *source = NULL;
+    float *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch  + xoffset * 16);
+        for (int x = 0; x < width; x++)
+        {
+            dest[4 * x + 0] = 0;
+            dest[4 * x + 1] = 0;
+            dest[4 * x + 2] = 0;
+            dest[4 * x + 3] = source[x];
+        }
+    }
+}
+
+void Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                          size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const unsigned short *source = NULL;
+    unsigned short *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
+        for (int x = 0; x < width; x++)
+        {
+            dest[4 * x + 0] = 0;
+            dest[4 * x + 1] = 0;
+            dest[4 * x + 2] = 0;
+            dest[4 * x + 3] = source[x];
+        }
+    }
+}
+
+void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                     size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
+{
+    const int destBytesPerPixel = native? 1: 4;
     const unsigned char *source = NULL;
     unsigned char *dest = NULL;
 
     for (int y = 0; y < height; y++)
     {
         source = static_cast<const unsigned char*>(input) + y * inputPitch;
-        dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+        dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * destBytesPerPixel;
+
+        if (!native)   // BGRA8 destination format
+        {
+            for (int x = 0; x < width; x++)
+            {
+                dest[4 * x + 0] = source[x];
+                dest[4 * x + 1] = source[x];
+                dest[4 * x + 2] = source[x];
+                dest[4 * x + 3] = 0xFF;
+            }
+        }
+        else   // L8 destination format
+        {
+            memcpy(dest, source, width);
+        }
+    }
+}
+
+void Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                          size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const float *source = NULL;
+    float *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch  + xoffset * 16);
         for (int x = 0; x < width; x++)
         {
             dest[4 * x + 0] = source[x];
             dest[4 * x + 1] = source[x];
             dest[4 * x + 2] = source[x];
-            dest[4 * x + 3] = 0xFF;
+            dest[4 * x + 3] = 1.0f;
+        }
+    }
+}
+
+void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                                   size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const unsigned short *source = NULL;
+    unsigned short *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
+        for (int x = 0; x < width; x++)
+        {
+            dest[4 * x + 0] = source[x];
+            dest[4 * x + 1] = source[x];
+            dest[4 * x + 2] = source[x];
+            dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
         }
     }
 }
 
 void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
-                                          size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+                                          size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
 {
+    const int destBytesPerPixel = native? 2: 4;
     const unsigned char *source = NULL;
     unsigned char *dest = NULL;
 
     for (int y = 0; y < height; y++)
     {
         source = static_cast<const unsigned char*>(input) + y * inputPitch;
-        dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+        dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * destBytesPerPixel;
+        
+        if (!native)   // BGRA8 destination format
+        {
+            for (int x = 0; x < width; x++)
+            {
+                dest[4 * x + 0] = source[2*x+0];
+                dest[4 * x + 1] = source[2*x+0];
+                dest[4 * x + 2] = source[2*x+0];
+                dest[4 * x + 3] = source[2*x+1];
+            }
+        }
+        else
+        {
+            memcpy(dest, source, width * 2);
+        }
+    }
+}
+
+void Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                               size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const float *source = NULL;
+    float *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch  + xoffset * 16);
+        for (int x = 0; x < width; x++)
+        {
+            dest[4 * x + 0] = source[2*x+0];
+            dest[4 * x + 1] = source[2*x+0];
+            dest[4 * x + 2] = source[2*x+0];
+            dest[4 * x + 3] = source[2*x+1];
+        }
+    }
+}
+
+void Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                                   size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const unsigned short *source = NULL;
+    unsigned short *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8);
         for (int x = 0; x < width; x++)
         {
             dest[4 * x + 0] = source[2*x+0];
@@ -362,6 +588,46 @@
     }
 }
 
+void Texture::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                    size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const float *source = NULL;
+    float *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch  + xoffset * 16);
+        for (int x = 0; x < width; x++)
+        {
+            dest[4 * x + 0] = source[x * 3 + 0];
+            dest[4 * x + 1] = source[x * 3 + 1];
+            dest[4 * x + 2] = source[x * 3 + 2];
+            dest[4 * x + 3] = 1.0f;
+        }
+    }
+}
+
+void Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                        size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const unsigned short *source = NULL;
+    unsigned short *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch  + xoffset * 8);
+        for (int x = 0; x < width; x++)
+        {
+            dest[4 * x + 0] = source[x * 3 + 0];
+            dest[4 * x + 1] = source[x * 3 + 1];
+            dest[4 * x + 2] = source[x * 3 + 2];
+            dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
+        }
+    }
+}
+
 void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                      size_t inputPitch, const void *input, size_t outputPitch, void *output) const
 {
@@ -424,6 +690,34 @@
     }
 }
 
+void Texture::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                     size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const float *source = NULL;
+    float *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch  + xoffset * 16);
+        memcpy(dest, source, width * 16);
+    }
+}
+
+void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                        size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+    const unsigned char *source = NULL;
+    unsigned char *dest = NULL;
+
+    for (int y = 0; y < height; y++)
+    {
+        source = static_cast<const unsigned char*>(input) + y * inputPitch;
+        dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch  + xoffset * 8;
+        memcpy(dest, source, width * 8);
+    }
+}
+
 void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                 size_t inputPitch, const void *input, size_t outputPitch, void *output) const
 {
@@ -438,7 +732,7 @@
     }
 }
 
-void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image *img)
+void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img)
 {
     IDirect3DTexture9 *newTexture = NULL;
     IDirect3DSurface9 *newSurface = NULL;
@@ -465,7 +759,7 @@
             levelToFetch = upsampleCount;
         }
 
-        HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format),
+        HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format, type),
                                                     D3DPOOL_SYSTEMMEM, &newTexture, NULL);
 
         if (FAILED(result))
@@ -488,10 +782,13 @@
 
 void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
 {
-    createSurface(width, height, format, img);
+    createSurface(width, height, format, type, img);
 
     if (pixels != NULL && img->surface != NULL)
     {
+        D3DSURFACE_DESC description;
+        img->surface->GetDesc(&description);
+
         D3DLOCKED_RECT locked;
         HRESULT result = img->surface->LockRect(&locked, NULL, 0);
 
@@ -499,7 +796,7 @@
 
         if (SUCCEEDED(result))
         {
-            loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
+            loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description);
             img->surface->UnlockRect();
         }
 
@@ -511,7 +808,7 @@
 
 void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img)
 {
-    createSurface(width, height, format, img);
+    createSurface(width, height, format, GL_UNSIGNED_BYTE, img);
 
     if (pixels != NULL && img->surface != NULL)
     {
@@ -540,18 +837,30 @@
         return false;
     }
 
-    D3DLOCKED_RECT locked;
-    HRESULT result = img->surface->LockRect(&locked, NULL, 0);
-
-    ASSERT(SUCCEEDED(result));
-
-    if (SUCCEEDED(result))
+    if (!img->surface)
     {
-        loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
-        img->surface->UnlockRect();
+        createSurface(img->width, img->height, format, type, img);
     }
 
-    img->dirty = true;
+    if (pixels != NULL && img->surface != NULL)
+    {
+        D3DSURFACE_DESC description;
+        img->surface->GetDesc(&description);
+
+        D3DLOCKED_RECT locked;
+        HRESULT result = img->surface->LockRect(&locked, NULL, 0);
+
+        ASSERT(SUCCEEDED(result));
+
+        if (SUCCEEDED(result))
+        {
+            loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description);
+            img->surface->UnlockRect();
+        }
+
+        img->dirty = true;
+    }
+
     return true;
 }
 
@@ -569,32 +878,215 @@
         return false;
     }
 
-    RECT updateRegion;
-    updateRegion.left = xoffset;
-    updateRegion.right = xoffset + width;
-    updateRegion.bottom = yoffset + height;
-    updateRegion.top = yoffset;
-
-    D3DLOCKED_RECT locked;
-    HRESULT result = img->surface->LockRect(&locked, &updateRegion, 0);
-
-    ASSERT(SUCCEEDED(result));
-
-    if (SUCCEEDED(result))
+    if (!img->surface)
     {
-        GLsizei inputPitch = ComputeCompressedPitch(width, format);
-        int rows = imageSize / inputPitch;
-        for (int i = 0; i < rows; ++i)
-        {
-            memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)pixels + i * inputPitch), inputPitch);
-        }
-        img->surface->UnlockRect();
+        createSurface(img->width, img->height, format, GL_UNSIGNED_BYTE, img);
     }
 
-    img->dirty = true;
+    if (pixels != NULL && img->surface != NULL)
+    {
+        RECT updateRegion;
+        updateRegion.left = xoffset;
+        updateRegion.right = xoffset + width;
+        updateRegion.bottom = yoffset + height;
+        updateRegion.top = yoffset;
+
+        D3DLOCKED_RECT locked;
+        HRESULT result = img->surface->LockRect(&locked, &updateRegion, 0);
+
+        ASSERT(SUCCEEDED(result));
+
+        if (SUCCEEDED(result))
+        {
+            GLsizei inputPitch = ComputeCompressedPitch(width, format);
+            int rows = imageSize / inputPitch;
+            for (int i = 0; i < rows; ++i)
+            {
+                memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)pixels + i * inputPitch), inputPitch);
+            }
+            img->surface->UnlockRect();
+        }
+
+        img->dirty = true;
+    }
+
     return true;
 }
 
+// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats
+void Texture::copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
+{
+    IDirect3DDevice9 *device = getDevice();
+    IDirect3DSurface9 *surface = NULL;
+    D3DSURFACE_DESC description;
+    renderTarget->GetDesc(&description);
+    
+    HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
+
+    if (!SUCCEEDED(result))
+    {
+        ERR("Could not create matching destination surface.");
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    result = device->GetRenderTargetData(renderTarget, surface);
+
+    if (!SUCCEEDED(result))
+    {
+        ERR("GetRenderTargetData unexpectedly failed.");
+        surface->Release();
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    D3DLOCKED_RECT sourceLock = {0};
+    RECT sourceRect = {x, y, x + width, y + height};
+    result = surface->LockRect(&sourceLock, &sourceRect, 0);
+
+    if (FAILED(result))
+    {
+        ERR("Failed to lock the source surface (rectangle might be invalid).");
+        surface->UnlockRect();
+        surface->Release();
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    if (!image->surface)
+    {
+        createSurface(width, height, internalFormat, mType, image);
+    }
+
+    if (image->surface == NULL)
+    {
+        ERR("Failed to create an image surface.");
+        surface->UnlockRect();
+        surface->Release();
+        return error(GL_OUT_OF_MEMORY); 
+    }
+
+    D3DLOCKED_RECT destLock = {0};
+    RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
+    result = image->surface->LockRect(&destLock, &destRect, 0);
+    
+    if (FAILED(result))
+    {
+        ERR("Failed to lock the destination surface (rectangle might be invalid).");
+        surface->UnlockRect();
+        surface->Release();
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    if (destLock.pBits && sourceLock.pBits)
+    {
+        unsigned char *source = (unsigned char*)sourceLock.pBits;
+        unsigned char *dest = (unsigned char*)destLock.pBits;
+
+        switch (description.Format)
+        {
+          case D3DFMT_X8R8G8B8:
+          case D3DFMT_A8R8G8B8:
+            switch(getD3DFormat())
+            {
+              case D3DFMT_L8:
+                for(int y = 0; y < height; y++)
+                {
+                    for(int x = 0; x < width; x++)
+                    {
+                        dest[x] = source[x * 4 + 2];
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              case D3DFMT_A8L8:
+                for(int y = 0; y < height; y++)
+                {
+                    for(int x = 0; x < width; x++)
+                    {
+                        dest[x * 2 + 0] = source[x * 4 + 2];
+                        dest[x * 2 + 1] = source[x * 4 + 3];
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              default:
+                UNREACHABLE();
+            }
+            break;
+          case D3DFMT_R5G6B5:
+            switch(getD3DFormat())
+            {
+              case D3DFMT_L8:
+                for(int y = 0; y < height; y++)
+                {
+                    for(int x = 0; x < width; x++)
+                    {
+                        unsigned char red = source[x * 2 + 1] & 0xF8;
+                        dest[x] = red | (red >> 5);
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              default:
+                UNREACHABLE();
+            }
+            break;
+          case D3DFMT_A1R5G5B5:
+            switch(getD3DFormat())
+            {
+              case D3DFMT_L8:
+                for(int y = 0; y < height; y++)
+                {
+                    for(int x = 0; x < width; x++)
+                    {
+                        unsigned char red = source[x * 2 + 1] & 0x7C;
+                        dest[x] = (red << 1) | (red >> 4);
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              case D3DFMT_A8L8:
+                for(int y = 0; y < height; y++)
+                {
+                    for(int x = 0; x < width; x++)
+                    {
+                        unsigned char red = source[x * 2 + 1] & 0x7C;
+                        dest[x * 2 + 0] = (red << 1) | (red >> 4);
+                        dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              default:
+                UNREACHABLE();
+            }
+            break;
+          default:
+            UNREACHABLE();
+        }
+
+        image->dirty = true;
+        mDirtyMetaData = true;    
+    }
+
+    image->surface->UnlockRect();
+    surface->UnlockRect();
+    surface->Release();
+}
+
+D3DFORMAT Texture::getD3DFormat() const
+{
+    return selectFormat(getFormat(), mType);
+}
+
 IDirect3DBaseTexture9 *Texture::getTexture()
 {
     if (!isComplete())
@@ -683,15 +1175,19 @@
     return mBaseTexture ? mBaseTexture->GetLevelCount() : 0;
 }
 
+bool Texture::isRenderable() const
+{
+    return mIsRenderable;
+}
+
 Texture2D::Texture2D(GLuint id) : Texture(id)
 {
     mTexture = NULL;
-    mColorbufferProxy = NULL;
 }
 
 Texture2D::~Texture2D()
 {
-    delete mColorbufferProxy;
+    mColorbufferProxy.set(NULL);
 
     if (mTexture)
     {
@@ -714,9 +1210,9 @@
 // for render-to-texture (such as CopyTexImage). We have no way of keeping individual inconsistent levels.
 // Call this when a particular level of the texture must be defined with a specific format, width and height.
 //
-// Returns true if the existing texture was unsuitable had to be destroyed. If so, it will also set
+// Returns true if the existing texture was unsuitable and had to be destroyed. If so, it will also set
 // a new height and width for the texture by working backwards from the given width and height.
-bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height)
+bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type)
 {
     bool widthOkay = (mWidth >> level == width);
     bool heightOkay = (mHeight >> level == height);
@@ -725,7 +1221,9 @@
                      || (widthOkay && mHeight >> level == 0 && height == 1)
                      || (heightOkay && mWidth >> level == 0 && width == 1));
 
-    bool textureOkay = (sizeOkay && internalFormat == mImageArray[0].format);
+    bool typeOkay = (type == mType);
+
+    bool textureOkay = (sizeOkay && typeOkay && internalFormat == mImageArray[0].format);
 
     if (!textureOkay)
     {
@@ -735,7 +1233,7 @@
 
         // Purge all the levels and the texture.
 
-        for (int i = 0; i < MAX_TEXTURE_LEVELS; i++)
+        for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
         {
             if (mImageArray[i].surface != NULL)
             {
@@ -756,6 +1254,7 @@
         mWidth = width << level;
         mHeight = height << level;
         mImageArray[0].format = internalFormat;
+        mType = type;
     }
 
     return !textureOkay;
@@ -763,14 +1262,14 @@
 
 void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
 {
-    redefineTexture(level, internalFormat, width, height);
+    redefineTexture(level, internalFormat, width, height, type);
 
     Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
 }
 
 void Texture2D::setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
 {
-    redefineTexture(level, internalFormat, width, height);
+    redefineTexture(level, internalFormat, width, height, GL_UNSIGNED_BYTE);
 
     Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[level]);
 }
@@ -828,29 +1327,46 @@
 
 void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
 {
-    if (redefineTexture(level, internalFormat, width, height))
+    IDirect3DSurface9 *renderTarget = source->getRenderTarget();
+
+    if (!renderTarget)
     {
-        convertToRenderTarget();
-        pushTexture(mTexture, true);
+        ERR("Failed to retrieve the render target.");
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    bool redefined = redefineTexture(level, internalFormat, width, height, mType);
+   
+    if (!isRenderableFormat())
+    {
+        copyNonRenderable(&mImageArray[level], internalFormat, 0, 0, x, y, width, height, renderTarget);
     }
     else
     {
-        needRenderTarget();
-    }
+        if (redefined)
+        {
+            convertToRenderTarget();
+            pushTexture(mTexture, true);
+        }
+        else
+        {
+            needRenderTarget();
+        }
 
-    if (width != 0 && height != 0 && level < levelCount())
-    {
-        RECT sourceRect;
-        sourceRect.left = x;
-        sourceRect.right = x + width;
-        sourceRect.top = y;
-        sourceRect.bottom = y + height;
+        if (width != 0 && height != 0 && level < levelCount())
+        {
+            RECT sourceRect;
+            sourceRect.left = x;
+            sourceRect.right = x + width;
+            sourceRect.top = y;
+            sourceRect.bottom = y + height;
 
-        IDirect3DSurface9 *dest;
-        HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
+            IDirect3DSurface9 *dest;
+            HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
 
-        getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
-        dest->Release();
+            getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
+            dest->Release();
+        }
     }
 
     mImageArray[level].width = width;
@@ -858,36 +1374,53 @@
     mImageArray[level].format = internalFormat;
 }
 
-void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
+void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
 {
     if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height)
     {
         return error(GL_INVALID_VALUE);
     }
 
-    if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height))
+    IDirect3DSurface9 *renderTarget = source->getRenderTarget();
+
+    if (!renderTarget)
     {
-        convertToRenderTarget();
-        pushTexture(mTexture, true);
+        ERR("Failed to retrieve the render target.");
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    bool redefined = redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height, mType);
+   
+    if (!isRenderableFormat())
+    {
+        copyNonRenderable(&mImageArray[level], getFormat(), xoffset, yoffset, x, y, width, height, renderTarget);
     }
     else
     {
-        needRenderTarget();
-    }
+        if (redefined)
+        {
+            convertToRenderTarget();
+            pushTexture(mTexture, true);
+        }
+        else
+        {
+            needRenderTarget();
+        }
 
-    if (level < levelCount())
-    {
-        RECT sourceRect;
-        sourceRect.left = x;
-        sourceRect.right = x + width;
-        sourceRect.top = y;
-        sourceRect.bottom = y + height;
+        if (level < levelCount())
+        {
+            RECT sourceRect;
+            sourceRect.left = x;
+            sourceRect.right = x + width;
+            sourceRect.top = y;
+            sourceRect.bottom = y + height;
 
-        IDirect3DSurface9 *dest;
-        HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
+            IDirect3DSurface9 *dest;
+            HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
 
-        getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, yoffset, dest);
-        dest->Release();
+            getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, yoffset, dest);
+            dest->Release();
+        }
     }
 }
 
@@ -919,6 +1452,16 @@
      default: UNREACHABLE();
     }
 
+    if ((getFormat() == GL_FLOAT && !getContext()->supportsFloatLinearFilter()) ||
+        (getFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatLinearFilter()))
+    {
+        if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
+        {
+            return false;
+        }
+    }
+
+
     if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width))
         || (getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height)))
     {
@@ -967,7 +1510,7 @@
     IDirect3DTexture9 *texture;
 
     IDirect3DDevice9 *device = getDevice();
-    D3DFORMAT format = selectFormat(mImageArray[0].format);
+    D3DFORMAT format = selectFormat(mImageArray[0].format, mType);
 
     HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL);
 
@@ -1018,7 +1561,7 @@
     {
         egl::Display *display = getDisplay();
         IDirect3DDevice9 *device = getDevice();
-        D3DFORMAT format = selectFormat(mImageArray[0].format);
+        D3DFORMAT format = selectFormat(mImageArray[0].format, mType);
 
         HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
 
@@ -1123,23 +1666,50 @@
         mImageArray[i].height = std::max(mImageArray[0].height >> i, 1);
     }
 
-    needRenderTarget();
-
-    for (unsigned int i = 1; i <= q; i++)
+    if (isRenderable())
     {
-        IDirect3DSurface9 *upper = NULL;
-        IDirect3DSurface9 *lower = NULL;
-
-        mTexture->GetSurfaceLevel(i-1, &upper);
-        mTexture->GetSurfaceLevel(i, &lower);
-
-        if (upper != NULL && lower != NULL)
+        if (mTexture == NULL)
         {
-            getBlitter()->boxFilter(upper, lower);
+            ERR(" failed because mTexture was null.");
+            return;
         }
 
-        if (upper != NULL) upper->Release();
-        if (lower != NULL) lower->Release();
+        for (unsigned int i = 1; i <= q; i++)
+        {
+            IDirect3DSurface9 *upper = NULL;
+            IDirect3DSurface9 *lower = NULL;
+
+            mTexture->GetSurfaceLevel(i-1, &upper);
+            mTexture->GetSurfaceLevel(i, &lower);
+
+            if (upper != NULL && lower != NULL)
+            {
+                getBlitter()->boxFilter(upper, lower);
+            }
+
+            if (upper != NULL) upper->Release();
+            if (lower != NULL) lower->Release();
+        }
+    }
+    else
+    {
+        for (unsigned int i = 1; i <= q; i++)
+        {
+            createSurface(mImageArray[i].width, mImageArray[i].height, mImageArray[i].format, mType, &mImageArray[i]);
+            if (mImageArray[i].surface == NULL)
+            {
+                return error(GL_OUT_OF_MEMORY);
+            }
+
+            if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[i].surface, NULL, NULL, mImageArray[i - 1].surface, NULL, NULL, D3DX_FILTER_BOX, 0)))
+            {
+                ERR(" failed to load filter %d to %d.", i - 1, i);
+            }
+
+            mImageArray[i].dirty = true;
+        }
+
+        mDirtyMetaData = true;
     }
 }
 
@@ -1150,13 +1720,12 @@
         return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
     }
 
-    if (mColorbufferProxy == NULL)
+    if (mColorbufferProxy.get() == NULL)
     {
-        mColorbufferProxy = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
-        mColorbufferProxy->addRef();
+        mColorbufferProxy.set(new Renderbuffer(id(), new TextureColorbufferProxy(this, target)));
     }
 
-    return mColorbufferProxy;
+    return mColorbufferProxy.get();
 }
 
 IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
@@ -1165,6 +1734,11 @@
 
     needRenderTarget();
 
+    if (mTexture == NULL)
+    {
+        return NULL;
+    }
+    
     IDirect3DSurface9 *renderTarget = NULL;
     mTexture->GetSurfaceLevel(0, &renderTarget);
 
@@ -1174,18 +1748,13 @@
 TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
 {
     mTexture = NULL;
-
-    for (int i = 0; i < 6; i++)
-    {
-        mFaceProxies[i] = NULL;
-    }
 }
 
 TextureCubeMap::~TextureCubeMap()
 {
     for (int i = 0; i < 6; i++)
     {
-        delete mFaceProxies[i];
+        mFaceProxies[i].set(NULL);
     }
 
     if (mTexture)
@@ -1277,19 +1846,19 @@
     }
 }
 
-void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
 {
-    if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(face)][level]))
+    if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(target)][level]))
     {
-        commitRect(face, level, xoffset, yoffset, width, height);
+        commitRect(target, level, xoffset, yoffset, width, height);
     }
 }
 
-void TextureCubeMap::subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
 {
-    if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[faceIndex(face)][level]))
+    if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[faceIndex(target)][level]))
     {
-        commitRect(face, level, xoffset, yoffset, width, height);
+        commitRect(target, level, xoffset, yoffset, width, height);
     }
 }
 
@@ -1328,6 +1897,15 @@
         }
     }
 
+    if ((getFormat() == GL_FLOAT && !getContext()->supportsFloatLinearFilter()) ||
+        (getFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatLinearFilter()))
+    {
+        if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
+        {
+            return false;
+        }
+    }
+
     if (mipmapping)
     {
         if (!isPow2(size) && (getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE))
@@ -1368,7 +1946,7 @@
 IDirect3DBaseTexture9 *TextureCubeMap::createTexture()
 {
     IDirect3DDevice9 *device = getDevice();
-    D3DFORMAT format = selectFormat(mImageArray[0][0].format);
+    D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType);
 
     IDirect3DCubeTexture9 *texture;
 
@@ -1424,7 +2002,7 @@
     {
         egl::Display *display = getDisplay();
         IDirect3DDevice9 *device = getDevice();
-        D3DFORMAT format = selectFormat(mImageArray[0][0].format);
+        D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType);
 
         HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
 
@@ -1546,7 +2124,7 @@
               internalFormat, width);
 
         // Purge all the levels and the texture.
-        for (int i = 0; i < MAX_TEXTURE_LEVELS; i++)
+        for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
         {
             for (int f = 0; f < 6; f++)
             {
@@ -1578,34 +2156,50 @@
     return !textureOkay;
 }
 
-void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
+void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
 {
-    unsigned int faceindex = faceIndex(face);
+    IDirect3DSurface9 *renderTarget = source->getRenderTarget();
 
-    if (redefineTexture(level, internalFormat, width))
+    if (!renderTarget)
     {
-        convertToRenderTarget();
-        pushTexture(mTexture, true);
+        ERR("Failed to retrieve the render target.");
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    unsigned int faceindex = faceIndex(target);
+    bool redefined = redefineTexture(level, internalFormat, width);
+
+    if (!isRenderableFormat())
+    {
+        copyNonRenderable(&mImageArray[faceindex][level], internalFormat, 0, 0, x, y, width, height, renderTarget);
     }
     else
     {
-        needRenderTarget();
-    }
+        if (redefined)
+        {
+            convertToRenderTarget();
+            pushTexture(mTexture, true);
+        }
+        else
+        {
+            needRenderTarget();
+        }
 
-    ASSERT(width == height);
+        ASSERT(width == height);
 
-    if (width > 0 && level < levelCount())
-    {
-        RECT sourceRect;
-        sourceRect.left = x;
-        sourceRect.right = x + width;
-        sourceRect.top = y;
-        sourceRect.bottom = y + height;
+        if (width > 0 && level < levelCount())
+        {
+            RECT sourceRect;
+            sourceRect.left = x;
+            sourceRect.right = x + width;
+            sourceRect.top = y;
+            sourceRect.bottom = y + height;
 
-        IDirect3DSurface9 *dest = getCubeMapSurface(face, level);
+            IDirect3DSurface9 *dest = getCubeMapSurface(target, level);
 
-        getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
-        dest->Release();
+            getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
+            dest->Release();
+        }
     }
 
     mImageArray[faceindex][level].width = width;
@@ -1644,37 +2238,55 @@
     return (SUCCEEDED(hr)) ? surface : NULL;
 }
 
-void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
+void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
 {
-    GLsizei size = mImageArray[faceIndex(face)][level].width;
+    GLsizei size = mImageArray[faceIndex(target)][level].width;
 
     if (xoffset + width > size || yoffset + height > size)
     {
         return error(GL_INVALID_VALUE);
     }
 
-    if (redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width))
+    IDirect3DSurface9 *renderTarget = source->getRenderTarget();
+
+    if (!renderTarget)
     {
-        convertToRenderTarget();
-        pushTexture(mTexture, true);
+        ERR("Failed to retrieve the render target.");
+        return error(GL_OUT_OF_MEMORY);
+    }
+
+    unsigned int faceindex = faceIndex(target);
+    bool redefined = redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width);
+   
+    if (!isRenderableFormat())
+    {
+        copyNonRenderable(&mImageArray[faceindex][level], getFormat(), 0, 0, x, y, width, height, renderTarget);
     }
     else
     {
-        needRenderTarget();
-    }
+        if (redefined)
+        {
+            convertToRenderTarget();
+            pushTexture(mTexture, true);
+        }
+        else
+        {
+            needRenderTarget();
+        }
 
-    if (level < levelCount())
-    {
-        RECT sourceRect;
-        sourceRect.left = x;
-        sourceRect.right = x + width;
-        sourceRect.top = y;
-        sourceRect.bottom = y + height;
+        if (level < levelCount())
+        {
+            RECT sourceRect;
+            sourceRect.left = x;
+            sourceRect.right = x + width;
+            sourceRect.top = y;
+            sourceRect.bottom = y + height;
 
-        IDirect3DSurface9 *dest = getCubeMapSurface(face, level);
+            IDirect3DSurface9 *dest = getCubeMapSurface(target, level);
 
-        getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, yoffset, dest);
-        dest->Release();
+            getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, yoffset, dest);
+            dest->Release();
+        }
     }
 }
 
@@ -1724,23 +2336,52 @@
         }
     }
 
-    needRenderTarget();
-
-    for (unsigned int f = 0; f < 6; f++)
+    if (isRenderable())
     {
-        for (unsigned int i = 1; i <= q; i++)
+        if (mTexture == NULL)
         {
-            IDirect3DSurface9 *upper = getCubeMapSurface(f, i-1);
-            IDirect3DSurface9 *lower = getCubeMapSurface(f, i);
-
-            if (upper != NULL && lower != NULL)
-            {
-                getBlitter()->boxFilter(upper, lower);
-            }
-
-            if (upper != NULL) upper->Release();
-            if (lower != NULL) lower->Release();
+            return;
         }
+
+        for (unsigned int f = 0; f < 6; f++)
+        {
+            for (unsigned int i = 1; i <= q; i++)
+            {
+                IDirect3DSurface9 *upper = getCubeMapSurface(f, i-1);
+                IDirect3DSurface9 *lower = getCubeMapSurface(f, i);
+
+                if (upper != NULL && lower != NULL)
+                {
+                    getBlitter()->boxFilter(upper, lower);
+                }
+
+                if (upper != NULL) upper->Release();
+                if (lower != NULL) lower->Release();
+            }
+        }
+    }
+    else
+    {
+        for (unsigned int f = 0; f < 6; f++)
+        {
+            for (unsigned int i = 1; i <= q; i++)
+            {
+                createSurface(mImageArray[f][i].width, mImageArray[f][i].height, mImageArray[f][i].format, mType, &mImageArray[f][i]);
+                if (mImageArray[f][i].surface == NULL)
+                {
+                    return error(GL_OUT_OF_MEMORY);
+                }
+
+                if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[f][i].surface, NULL, NULL, mImageArray[f][i - 1].surface, NULL, NULL, D3DX_FILTER_BOX, 0)))
+                {
+                    ERR(" failed to load filter %d to %d.", i - 1, i);
+                }
+
+                mImageArray[f][i].dirty = true;
+            }
+        }
+
+        mDirtyMetaData = true;
     }
 }
 
@@ -1753,13 +2394,12 @@
 
     unsigned int face = faceIndex(target);
 
-    if (mFaceProxies[face] == NULL)
+    if (mFaceProxies[face].get() == NULL)
     {
-        mFaceProxies[face] = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
-        mFaceProxies[face]->addRef();
+        mFaceProxies[face].set(new Renderbuffer(id(), new TextureColorbufferProxy(this, target)));
     }
 
-    return mFaceProxies[face];
+    return mFaceProxies[face].get();
 }
 
 IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
@@ -1767,7 +2407,12 @@
     ASSERT(IsCubemapTextureTarget(target));
 
     needRenderTarget();
-
+    
+    if (mTexture == NULL)
+    {
+        return NULL;
+    }
+    
     IDirect3DSurface9 *renderTarget = NULL;
     mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(faceIndex(target)), 0, &renderTarget);
 
@@ -1775,9 +2420,9 @@
 }
 
 Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLenum target)
-  : Colorbuffer(NULL), mTexture(texture), mTarget(target)
+  : Colorbuffer(texture), mTexture(texture), mTarget(target)
 {
-    ASSERT(target == GL_TEXTURE_2D || IsCubemapTextureTarget(target));
+    ASSERT(IsTextureTarget(target));
 }
 
 void Texture::TextureColorbufferProxy::addRef() const
@@ -1814,4 +2459,9 @@
     return mTexture->getFormat();
 }
 
+bool Texture::TextureColorbufferProxy::isFloatingPoint() const
+{
+    return mTexture->isFloatingPoint();
+}
+
 }
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h
index efa882c..ca7aec7 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h
@@ -18,6 +18,7 @@
 #include <d3d9.h>
 
 #include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/RefCountObject.h"
 #include "libGLESv2/utilities.h"
 #include "common/debug.h"
 
@@ -27,10 +28,13 @@
 
 enum
 {
-    MAX_TEXTURE_SIZE = 2048,
-    MAX_CUBE_MAP_TEXTURE_SIZE = 2048,
+    // These are the maximums the implementation can support
+    // The actual GL caps are limited by the device caps
+    // and should be queried from the Context
+    IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384,
+    IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
 
-    MAX_TEXTURE_LEVELS = 12   // 1+log2 of MAX_TEXTURE_SIZE
+    IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15   // 1+log2 of MAX_TEXTURE_SIZE
 };
 
 class Texture : public RefCountObject
@@ -58,11 +62,15 @@
     virtual GLenum getFormat() const = 0;
     virtual bool isComplete() const = 0;
     virtual bool isCompressed() const = 0;
+    bool isFloatingPoint() const;
+    bool isRenderableFormat() const;
 
+    D3DFORMAT getD3DFormat() const;
     IDirect3DBaseTexture9 *getTexture();
     virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
 
     virtual void generateMipmaps() = 0;
+    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) = 0;
 
     bool isDirty() const;
 
@@ -85,6 +93,7 @@
         virtual int getWidth() const;
         virtual int getHeight() const;
         virtual GLenum getFormat() const;
+        virtual bool isFloatingPoint() const;
 
       private:
         Texture *mTexture;
@@ -106,13 +115,13 @@
         IDirect3DSurface9 *surface;
     };
 
-    static D3DFORMAT selectFormat(GLenum format);
-    int imagePitch(const Image& img) const;
+    static D3DFORMAT selectFormat(GLenum format, GLenum type);
 
     void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
     bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
     void setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
     bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
+    void copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
 
     void needRenderTarget();
 
@@ -129,50 +138,73 @@
 
     void dropTexture();
     void pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable);
+    void createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img);
 
     Blit *getBlitter();
 
     int levelCount() const;
 
+    bool isRenderable() const;
+
     unsigned int mWidth;
     unsigned int mHeight;
     GLenum mMinFilter;
     GLenum mMagFilter;
     GLenum mWrapS;
     GLenum mWrapT;
+    GLenum mType;
+
+    bool mDirtyMetaData;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture);
 
     void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
-                       GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
+                       GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output, D3DSURFACE_DESC *description) const;
 
     void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                             size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
-    void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
-                                size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
-    void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+    void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                 size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                      size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
+    void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                     size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                         size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                     size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
+    void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                          size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                              size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
     void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
     void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                              size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                               size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                   size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
     void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                 size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
     void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
     void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+    void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                    size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
     void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                            size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
 
     IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
 
     bool mDirty;
-    bool mDirtyMetaData;
     bool mIsRenderable;
-
-    void createSurface(GLsizei width, GLsizei height, GLenum format, Image *img);
 };
 
 class Texture2D : public Texture
@@ -190,7 +222,7 @@
     void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
     void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
-    void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+    void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
 
     bool isComplete() const;
     bool isCompressed() const;
@@ -209,14 +241,14 @@
 
     virtual bool dirtyImageData() const;
 
-    bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
+    bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type);
     void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
 
-    Image mImageArray[MAX_TEXTURE_LEVELS];
+    Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
     IDirect3DTexture9 *mTexture;
 
-    Renderbuffer *mColorbufferProxy;
+    BindingPointer<Renderbuffer> mColorbufferProxy;
 };
 
 class TextureCubeMap : public Texture
@@ -238,10 +270,10 @@
 
     void setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
 
-    void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
-    void subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
-    void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
-    void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+    void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+    void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+    void copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+    void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
 
     bool isComplete() const;
     bool isCompressed() const;
@@ -272,11 +304,11 @@
     void commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
     bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width);
 
-    Image mImageArray[6][MAX_TEXTURE_LEVELS];
+    Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
     IDirect3DCubeTexture9 *mTexture;
 
-    Renderbuffer *mFaceProxies[6];
+    BindingPointer<Renderbuffer> mFaceProxies[6];
 };
 }
 
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp
index d573579..f79d606 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp
@@ -13,7 +13,7 @@
 
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/mathutil.h"
-#include "libGLESv2/geometry/backend.h"
+#include "libGLESv2/main.h"
 
 namespace
 {
@@ -23,239 +23,360 @@
 namespace gl
 {
 
-IndexDataManager::IndexDataManager(Context *context, BufferBackEnd *backend)
-  : mContext(context), mBackend(backend), mIntIndicesSupported(backend->supportIntIndices())
+IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : mDevice(device)
 {
-    mCountingBuffer = NULL;
-    mCountingBufferSize = 0;
+    mStreamingBufferShort = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
 
-    mLineLoopBuffer = NULL;
-
-    mStreamBufferShort = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT);
-
-    if (mIntIndicesSupported)
+    if (context->supports32bitIndices())
     {
-        mStreamBufferInt = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+        mStreamingBufferInt = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
     }
     else
     {
-        mStreamBufferInt = NULL;
+        mStreamingBufferInt = NULL;
     }
 }
 
 IndexDataManager::~IndexDataManager()
 {
-    delete mStreamBufferShort;
-    delete mStreamBufferInt;
-    delete mCountingBuffer;
-    delete mLineLoopBuffer;
+    delete mStreamingBufferShort;
+    delete mStreamingBufferInt;
 }
 
-namespace
+void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
 {
+    if (type == GL_UNSIGNED_BYTE)
+    {
+        const GLubyte *in = static_cast<const GLubyte*>(input);
+        GLushort *out = static_cast<GLushort*>(output);
 
-template <class InputIndexType, class OutputIndexType>
-void copyIndices(const InputIndexType *in, GLsizei count, OutputIndexType *out, GLuint *minIndex, GLuint *maxIndex)
+        for (GLsizei i = 0; i < count; i++)
+        {
+            out[i] = in[i];
+        }
+    }
+    else if (type == GL_UNSIGNED_INT)
+    {
+        memcpy(output, input, count * sizeof(GLuint));
+    }
+    else if (type == GL_UNSIGNED_SHORT)
+    {
+        memcpy(output, input, count * sizeof(GLushort));
+    }
+    else UNREACHABLE();
+}
+
+template <class IndexType>
+void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
 {
-    InputIndexType first = *in;
-    GLuint minIndexSoFar = first;
-    GLuint maxIndexSoFar = first;
+    *minIndex = indices[0];
+    *maxIndex = indices[0];
 
     for (GLsizei i = 0; i < count; i++)
     {
-        if (minIndexSoFar > *in) minIndexSoFar = *in;
-        if (maxIndexSoFar < *in) maxIndexSoFar = *in;
-
-        *out++ = *in++;
+        if (*minIndex > indices[i]) *minIndex = indices[i];
+        if (*maxIndex < indices[i]) *maxIndex = indices[i];
     }
-
-    // It might be a line loop, so copy the loop index.
-    *out = first;
-
-    *minIndex = minIndexSoFar;
-    *maxIndex = maxIndexSoFar;
 }
 
-}
-
-GLenum IndexDataManager::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated)
+void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
 {
-    ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT);
-    ASSERT(count > 0);
-
-    if (arrayElementBuffer != NULL)
+    if (type == GL_UNSIGNED_BYTE)
     {
-        GLsizei offset = reinterpret_cast<GLsizei>(indices);
+        computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
+    }
+    else if (type == GL_UNSIGNED_INT)
+    {
+        computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
+    }
+    else if (type == GL_UNSIGNED_SHORT)
+    {
+        computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
+    }
+    else UNREACHABLE();
+}
 
-        if (typeSize(type) * count + offset > static_cast<std::size_t>(arrayElementBuffer->size()))
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
+{
+    D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
+    intptr_t offset = reinterpret_cast<intptr_t>(indices);
+    bool alignedOffset = false;
+
+    if (buffer != NULL)
+    {
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:  alignedOffset = (offset % sizeof(GLubyte) == 0);  break;
+          case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
+          case GL_UNSIGNED_INT:   alignedOffset = (offset % sizeof(GLuint) == 0);   break;
+          default: UNREACHABLE(); alignedOffset = false;
+        }
+
+        if (typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
         {
             return GL_INVALID_OPERATION;
         }
 
-        indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + offset;
+        indices = static_cast<const GLubyte*>(buffer->data()) + offset;
     }
 
-    translated->count = count;
+    StreamingIndexBuffer *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
 
-    std::size_t requiredSpace = spaceRequired(type, count);
+    StaticIndexBuffer *staticBuffer = buffer ? buffer->getIndexBuffer() : NULL;
+    IndexBuffer *indexBuffer = streamingBuffer;
+    UINT streamOffset = 0;
 
-    TranslatedIndexBuffer *streamIb = prepareIndexBuffer(type, requiredSpace);
-
-    size_t offset;
-    void *output = streamIb->map(requiredSpace, &offset);
-
-    translated->buffer = streamIb;
-    translated->offset = offset;
-    translated->indexSize = indexSize(type);
-
-    if (type == GL_UNSIGNED_BYTE)
+    if (staticBuffer && staticBuffer->lookupType(type) && alignedOffset)
     {
-        const GLubyte *in = static_cast<const GLubyte*>(indices);
-        GLushort *out = static_cast<GLushort*>(output);
+        indexBuffer = staticBuffer;
+        streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex);
 
-        copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
-    }
-    else if (type == GL_UNSIGNED_INT)
-    {
-        const GLuint *in = static_cast<const GLuint*>(indices);
-
-        if (mIntIndicesSupported)
+        if (streamOffset == -1)
         {
-            GLuint *out = static_cast<GLuint*>(output);
-
-            copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
-        }
-        else
-        {
-            // When 32-bit indices are unsupported, fake them by truncating to 16-bit.
-
-            GLushort *out = static_cast<GLushort*>(output);
-
-            copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
+            streamOffset = (offset / typeSize(type)) * indexSize(format);
+            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+            staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
         }
     }
     else
     {
-        const GLushort *in = static_cast<const GLushort*>(indices);
-        GLushort *out = static_cast<GLushort*>(output);
+        int convertCount = count;
 
-        copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
+        if (staticBuffer)
+        {
+            if (staticBuffer->size() == 0 && alignedOffset)
+            {
+                indexBuffer = staticBuffer;
+                convertCount = buffer->size() / typeSize(type);
+            }
+            else
+            {
+                buffer->invalidateStaticData();
+                staticBuffer = NULL;
+            }
+        }
+
+        void *output = NULL;
+        
+        if (indexBuffer)
+        {
+            indexBuffer->reserveSpace(convertCount * indexSize(format), type);
+            output = indexBuffer->map(indexSize(format) * convertCount, &streamOffset);
+        }
+        
+        if (output == NULL)
+        {
+            ERR("Failed to map index buffer.");
+            return GL_OUT_OF_MEMORY;
+        }
+
+        convertIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
+        indexBuffer->unmap();
+
+        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+        if (staticBuffer)
+        {
+            streamOffset = (offset / typeSize(type)) * indexSize(format);
+            staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
+        }
     }
 
-    streamIb->unmap();
+    translated->indexBuffer = indexBuffer->getBuffer();
+    translated->startIndex = streamOffset / indexSize(format);
 
     return GL_NO_ERROR;
 }
 
-std::size_t IndexDataManager::indexSize(GLenum type) const
+std::size_t IndexDataManager::indexSize(D3DFORMAT format) const
 {
-    return (type == GL_UNSIGNED_INT && mIntIndicesSupported) ? sizeof(GLuint) : sizeof(GLushort);
+    return (format == D3DFMT_INDEX32) ? sizeof(unsigned int) : sizeof(unsigned short);
 }
 
 std::size_t IndexDataManager::typeSize(GLenum type) const
 {
     switch (type)
     {
-      case GL_UNSIGNED_INT: return sizeof(GLuint);
+      case GL_UNSIGNED_INT:   return sizeof(GLuint);
       case GL_UNSIGNED_SHORT: return sizeof(GLushort);
-      default: UNREACHABLE();
-      case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+      case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);
+      default: UNREACHABLE(); return sizeof(GLushort);
     }
 }
 
-std::size_t IndexDataManager::spaceRequired(GLenum type, GLsizei count) const
+IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL)
 {
-    return (count + 1) * indexSize(type); // +1 because we always leave an extra for line loops
+    if (size > 0)
+    {
+        D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
+        HRESULT result = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, pool, &mIndexBuffer, NULL);
+
+        if (FAILED(result))
+        {
+            ERR("Out of memory allocating an index buffer of size %lu.", size);
+        }
+    }
 }
 
-TranslatedIndexBuffer *IndexDataManager::prepareIndexBuffer(GLenum type, std::size_t requiredSpace)
+IndexBuffer::~IndexBuffer()
 {
-    bool use32 = (type == GL_UNSIGNED_INT && mIntIndicesSupported);
-
-    TranslatedIndexBuffer *streamIb = use32 ? mStreamBufferInt : mStreamBufferShort;
-
-    if (requiredSpace > streamIb->size())
+    if (mIndexBuffer)
     {
-        std::size_t newSize = std::max(requiredSpace, 2 * streamIb->size());
-
-        TranslatedIndexBuffer *newStreamBuffer = mBackend->createIndexBuffer(newSize, use32 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT);
-
-        delete streamIb;
-
-        streamIb = newStreamBuffer;
-
-        if (use32)
-        {
-            mStreamBufferInt = streamIb;
-        }
-        else
-        {
-            mStreamBufferShort = streamIb;
-        }
+        mIndexBuffer->Release();
     }
-
-    streamIb->reserveSpace(requiredSpace);
-
-    return streamIb;
 }
 
-GLenum IndexDataManager::preRenderValidateUnindexed(GLenum mode, GLsizei count, TranslatedIndexData *indexInfo)
+IDirect3DIndexBuffer9 *IndexBuffer::getBuffer() const
 {
-    if (count >= 65535) return GL_OUT_OF_MEMORY;
+    return mIndexBuffer;
+}
 
-    if (mode == GL_LINE_LOOP)
+void IndexBuffer::unmap()
+{
+    if (mIndexBuffer)
     {
-        // For line loops, create a single-use buffer that runs 0 - count-1, 0.
-        delete mLineLoopBuffer;
-        mLineLoopBuffer = mBackend->createIndexBuffer((count+1) * sizeof(unsigned short), GL_UNSIGNED_SHORT);
+        mIndexBuffer->Unlock();
+    }
+}
 
-        unsigned short *indices = static_cast<unsigned short *>(mLineLoopBuffer->map());
+StreamingIndexBuffer::StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format) : IndexBuffer(device, initialSize, format)
+{
+    mWritePosition = 0;
+}
 
-        for (int i = 0; i < count; i++)
+StreamingIndexBuffer::~StreamingIndexBuffer()
+{
+}
+
+void *StreamingIndexBuffer::map(UINT requiredSpace, UINT *offset)
+{
+    void *mapPtr = NULL;
+
+    if (mIndexBuffer)
+    {
+        HRESULT result = mIndexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
+     
+        if (FAILED(result))
         {
-            indices[i] = i;
+            ERR(" Lock failed with error 0x%08x", result);
+            return NULL;
         }
 
-        indices[count] = 0;
-
-        mLineLoopBuffer->unmap();
-
-        indexInfo->buffer = mLineLoopBuffer;
-        indexInfo->count = count + 1;
-        indexInfo->maxIndex = count - 1;
+        *offset = mWritePosition;
+        mWritePosition += requiredSpace;
     }
-    else if (mCountingBufferSize < count)
+
+    return mapPtr;
+}
+
+void StreamingIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
+{
+    if (requiredSpace > mBufferSize)
     {
-        mCountingBufferSize = std::max(static_cast<GLsizei>(ceilPow2(count)), mCountingBufferSize*2);
-
-        delete mCountingBuffer;
-        mCountingBuffer = mBackend->createIndexBuffer(count * sizeof(unsigned short), GL_UNSIGNED_SHORT);
-
-        unsigned short *indices = static_cast<unsigned short *>(mCountingBuffer->map());
-
-        for (int i = 0; i < count; i++)
+        if (mIndexBuffer)
         {
-            indices[i] = i;
+            mIndexBuffer->Release();
+            mIndexBuffer = NULL;
         }
 
-        mCountingBuffer->unmap();
+        mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
 
-        indexInfo->buffer = mCountingBuffer;
-        indexInfo->count = count;
-        indexInfo->maxIndex = count - 1;
+        D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
+        HRESULT result = mDevice->CreateIndexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
+    
+        if (FAILED(result))
+        {
+            ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
+        }
+
+        mWritePosition = 0;
     }
-    else
+    else if (mWritePosition + requiredSpace > mBufferSize)   // Recycle
     {
-        indexInfo->buffer = mCountingBuffer;
-        indexInfo->count = count;
-        indexInfo->maxIndex = count - 1;
+        void *dummy;
+        mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+        mIndexBuffer->Unlock();
+
+        mWritePosition = 0;
+    }
+}
+
+StaticIndexBuffer::StaticIndexBuffer(IDirect3DDevice9 *device) : IndexBuffer(device, 0, D3DFMT_UNKNOWN)
+{
+    mCacheType = GL_NONE;
+}
+
+StaticIndexBuffer::~StaticIndexBuffer()
+{
+}
+
+void *StaticIndexBuffer::map(UINT requiredSpace, UINT *offset)
+{
+    void *mapPtr = NULL;
+
+    if (mIndexBuffer)
+    {
+        HRESULT result = mIndexBuffer->Lock(0, requiredSpace, &mapPtr, 0);
+     
+        if (FAILED(result))
+        {
+            ERR(" Lock failed with error 0x%08x", result);
+            return NULL;
+        }
+
+        *offset = 0;
     }
 
-    indexInfo->indexSize = sizeof(unsigned short);
-    indexInfo->minIndex = 0;
-    indexInfo->offset = 0;
+    return mapPtr;
+}
 
-    return GL_NO_ERROR;
+void StaticIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
+{
+    if (!mIndexBuffer && mBufferSize == 0)
+    {
+        D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
+        HRESULT result = mDevice->CreateIndexBuffer(requiredSpace, D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
+    
+        if (FAILED(result))
+        {
+            ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
+        }
+
+        mBufferSize = requiredSpace;
+        mCacheType = type;
+    }
+    else if (mIndexBuffer && mBufferSize >= requiredSpace && mCacheType == type)
+    {
+        // Already allocated
+    }
+    else UNREACHABLE();   // Static index buffers can't be resized
+}
+
+bool StaticIndexBuffer::lookupType(GLenum type)
+{
+    return mCacheType == type;
+}
+
+UINT StaticIndexBuffer::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex)
+{
+    for (unsigned int range = 0; range < mCache.size(); range++)
+    {
+        if (mCache[range].offset == offset && mCache[range].count == count)
+        {
+            *minIndex = mCache[range].minIndex;
+            *maxIndex = mCache[range].maxIndex;
+
+            return mCache[range].streamOffset;
+        }
+    }
+
+    return -1;
+}
+
+void StaticIndexBuffer::addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset)
+{
+    IndexRange indexRange = {offset, count, minIndex, maxIndex, streamOffset};
+    mCache.push_back(indexRange);
 }
 
 }
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h
index 00ebed25..d48249c 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h
@@ -10,7 +10,7 @@
 #ifndef LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
 #define LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
 
-#include <bitset>
+#include <vector>
 #include <cstddef>
 
 #define GL_APICALL
@@ -21,49 +21,98 @@
 namespace gl
 {
 
-class Buffer;
-class BufferBackEnd;
-class TranslatedIndexBuffer;
-struct FormatConverter;
-
 struct TranslatedIndexData
 {
-    GLuint minIndex;
-    GLuint maxIndex;
-    GLuint count;
-    GLuint indexSize;
+    UINT minIndex;
+    UINT maxIndex;
+    UINT startIndex;
 
-    TranslatedIndexBuffer *buffer;
-    GLsizei offset;
+    IDirect3DIndexBuffer9 *indexBuffer;
+};
+
+class IndexBuffer
+{
+  public:
+    IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format);
+    virtual ~IndexBuffer();
+
+    UINT size() const { return mBufferSize; }
+    virtual void *map(UINT requiredSpace, UINT *offset) = 0;
+    void unmap();
+    virtual void reserveSpace(UINT requiredSpace, GLenum type) = 0;
+
+    IDirect3DIndexBuffer9 *getBuffer() const;
+
+  protected:
+    IDirect3DDevice9 *const mDevice;
+
+    IDirect3DIndexBuffer9 *mIndexBuffer;
+    UINT mBufferSize;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
+};
+
+class StreamingIndexBuffer : public IndexBuffer
+{
+  public:
+    StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format);
+    ~StreamingIndexBuffer();
+
+    void *map(UINT requiredSpace, UINT *offset);
+    void reserveSpace(UINT requiredSpace, GLenum type);
+
+  private:
+    UINT mWritePosition;
+};
+
+class StaticIndexBuffer : public IndexBuffer
+{
+  public:
+    explicit StaticIndexBuffer(IDirect3DDevice9 *device);
+    ~StaticIndexBuffer();
+
+    void *map(UINT requiredSpace, UINT *offset);
+    void reserveSpace(UINT requiredSpace, GLenum type);
+
+    bool lookupType(GLenum type);
+    UINT lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex);   // Returns the offset into the index buffer, or -1 if not found
+    void addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset);
+
+  private:
+    GLenum mCacheType;
+    
+    struct IndexRange
+    {
+        intptr_t offset;
+        GLsizei count;
+
+        UINT minIndex;
+        UINT maxIndex;
+        UINT streamOffset;
+    };
+
+    std::vector<IndexRange> mCache;
 };
 
 class IndexDataManager
 {
   public:
-    IndexDataManager(Context *context, BufferBackEnd *backend);
-    ~IndexDataManager();
+    IndexDataManager(Context *context, IDirect3DDevice9 *evice);
+    virtual ~IndexDataManager();
 
-    GLenum preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
-    GLenum preRenderValidateUnindexed(GLenum mode, GLsizei count, TranslatedIndexData *indexInfo);
+    GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
 
   private:
-    std::size_t IndexDataManager::typeSize(GLenum type) const;
-    std::size_t IndexDataManager::indexSize(GLenum type) const;
-    std::size_t spaceRequired(GLenum type, GLsizei count) const;
-    TranslatedIndexBuffer *prepareIndexBuffer(GLenum type, std::size_t requiredSpace);
+    DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
 
-    Context *mContext;
-    BufferBackEnd *mBackend;
+    std::size_t typeSize(GLenum type) const;
+    std::size_t indexSize(D3DFORMAT format) const;
 
-    bool mIntIndicesSupported;
+    IDirect3DDevice9 *const mDevice;
 
-    TranslatedIndexBuffer *mStreamBufferShort;
-    TranslatedIndexBuffer *mStreamBufferInt;
-
-    TranslatedIndexBuffer *mCountingBuffer;
-    GLsizei mCountingBufferSize;
-
-    TranslatedIndexBuffer *mLineLoopBuffer;
+    StreamingIndexBuffer *mStreamingBufferShort;
+    StreamingIndexBuffer *mStreamingBufferInt;
 };
 
 }
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp
index 7762e07..99ece17 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp
@@ -9,14 +9,13 @@
 
 #include "libGLESv2/geometry/VertexDataManager.h"
 
-#include <limits>
-
 #include "common/debug.h"
 
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Program.h"
+#include "libGLESv2/main.h"
 
-#include "libGLESv2/geometry/backend.h"
+#include "libGLESv2/geometry/vertexconversion.h"
 #include "libGLESv2/geometry/IndexDataManager.h"
 
 namespace
@@ -27,245 +26,744 @@
 namespace gl
 {
 
-VertexDataManager::VertexDataManager(Context *context, BufferBackEnd *backend)
-    : mContext(context), mBackend(backend), mDirtyCurrentValues(true), mCurrentValueOffset(0)
+VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device)
 {
-    mStreamBuffer = mBackend->createVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);
-    try
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
-        mCurrentValueBuffer = mBackend->createVertexBufferForStrideZero(4 * sizeof(float) * MAX_VERTEX_ATTRIBS);
+        mDirtyCurrentValue[i] = true;
+        mCurrentValueBuffer[i] = NULL;
     }
-    catch (...)
-    {
-        delete mStreamBuffer;
-        throw;
-    }
+
+    const D3DCAPS9 &caps = context->getDeviceCaps();
+    checkVertexCaps(caps.DeclTypes);
+
+    mStreamingBuffer = new StreamingVertexBuffer(mDevice, INITIAL_STREAM_BUFFER_SIZE);
 }
 
 VertexDataManager::~VertexDataManager()
 {
-    delete mStreamBuffer;
-    delete mCurrentValueBuffer;
+    delete mStreamingBuffer;
+
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    {
+        delete mCurrentValueBuffer[i];
+    }
 }
 
-std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::getActiveAttribs() const
+UINT VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
 {
-    std::bitset<MAX_VERTEX_ATTRIBS> active;
+    Buffer *buffer = attribute.mBoundBuffer.get();
 
+    int inputStride = attribute.stride();
+    int elementSize = attribute.typeSize();
+    const FormatConverter &converter = formatConverter(attribute);
+    UINT streamOffset = 0;
+
+    void *output = NULL;
+    
+    if (vertexBuffer)
+    {
+        output = vertexBuffer->map(attribute, spaceRequired(attribute, count), &streamOffset);
+    }
+
+    if (output == NULL)
+    {
+        ERR("Failed to map vertex buffer.");
+        return -1;
+    }
+
+    const char *input = NULL;
+
+    if (buffer)
+    {
+        int offset = attribute.mOffset;
+
+        input = static_cast<const char*>(buffer->data()) + offset;
+    }
+    else
+    {
+        input = static_cast<const char*>(attribute.mPointer);
+    }
+
+    input += inputStride * start;
+
+    if (converter.identity && inputStride == elementSize)
+    {
+        memcpy(output, input, count * inputStride);
+    }
+    else
+    {
+        converter.convertArray(input, inputStride, count, output);
+    }
+
+    vertexBuffer->unmap();
+
+    return streamOffset;
+}
+
+GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
+{
+    GLenum error = GL_NO_ERROR;
+    const VertexAttributeArray &attribs = mContext->getVertexAttributes();
     Program *program = mContext->getCurrentProgram();
 
     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
     {
-        active[attributeIndex] = (program->getSemanticIndex(attributeIndex) != -1);
+        translated[attributeIndex].active = (program->getSemanticIndex(attributeIndex) != -1);
     }
 
-    return active;
-}
-
-GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
-                                            TranslatedAttribute *translated)
-{
-    const AttributeState *attribs = mContext->getVertexAttribBlock();
-    const std::bitset<MAX_VERTEX_ATTRIBS> activeAttribs = getActiveAttribs();
-
+    // Determine the required storage size per used buffer
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
-        if (!activeAttribs[i] && attribs[i].mEnabled && attribs[i].mBoundBuffer != 0 && !mContext->getBuffer(attribs[i].mBoundBuffer))
-            return GL_INVALID_OPERATION;
-    }
+        Buffer *buffer = attribs[i].mBoundBuffer.get();
 
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        translated[i].enabled = activeAttribs[i];
-    }
-
-    bool usesCurrentValues = false;
-
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (activeAttribs[i] && !attribs[i].mEnabled)
+        if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
         {
-            usesCurrentValues = true;
-            break;
-        }
-    }
+            StaticVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
 
-    // Handle the identity-mapped attributes.
-    // Process array attributes.
-
-    std::size_t requiredSpace = 0;
-
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (activeAttribs[i] && attribs[i].mEnabled)
-        {
-            requiredSpace += spaceRequired(attribs[i], count);
-        }
-    }
-
-    if (requiredSpace > mStreamBuffer->size())
-    {
-        std::size_t newSize = std::max(requiredSpace, 3 * mStreamBuffer->size() / 2); // 1.5 x mStreamBuffer->size() is arbitrary and should be checked to see we don't have too many reallocations.
-
-        TranslatedVertexBuffer *newStreamBuffer = mBackend->createVertexBuffer(newSize);
-
-        delete mStreamBuffer;
-        mStreamBuffer = newStreamBuffer;
-    }
-
-    mStreamBuffer->reserveSpace(requiredSpace);
-
-    for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (activeAttribs[i] && attribs[i].mEnabled)
-        {
-            FormatConverter formatConverter = mBackend->getFormatConverter(attribs[i].mType, attribs[i].mSize, attribs[i].mNormalized);
-
-            translated[i].nonArray = false;
-            translated[i].type = attribs[i].mType;
-            translated[i].size = attribs[i].mSize;
-            translated[i].normalized = attribs[i].mNormalized;
-            translated[i].stride = formatConverter.outputVertexSize;
-            translated[i].buffer = mStreamBuffer;
-
-            size_t inputStride = interpretGlStride(attribs[i]);
-            size_t elementSize = typeSize(attribs[i].mType) * attribs[i].mSize;
-
-            void *output = mStreamBuffer->map(spaceRequired(attribs[i], count), &translated[i].offset);
-
-            const void *input;
-            if (attribs[i].mBoundBuffer)
+            if (staticBuffer && staticBuffer->size() == 0)
             {
-                Buffer *buffer = mContext->getBuffer(attribs[i].mBoundBuffer);
-
-                size_t offset = reinterpret_cast<size_t>(attribs[i].mPointer);
-
-                // Before we calculate the required size below, make sure it can be computed without integer overflow.
-                if (std::numeric_limits<std::size_t>::max() - start < static_cast<std::size_t>(count)
-                    || std::numeric_limits<std::size_t>::max() / inputStride < static_cast<std::size_t>(start + count - 1) // it's a prerequisite that count >= 1, so start+count-1 >= 0.
-                    || std::numeric_limits<std::size_t>::max() - offset < inputStride * (start + count - 1)
-                    || std::numeric_limits<std::size_t>::max() - elementSize < offset + inputStride * (start + count - 1) + elementSize)
+                int totalCount = buffer->size() / attribs[i].stride();
+                staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
+            }
+            else if (!staticBuffer || staticBuffer->lookupAttribute(attribs[i]) == -1)
+            {
+                if (mStreamingBuffer)
                 {
-                    mStreamBuffer->unmap();
+                    mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
+                }
+            }
+        }
+    }
+
+    // Invalidate static buffers if the attribute formats no longer match
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    {
+        Buffer *buffer = attribs[i].mBoundBuffer.get();
+
+        if (translated[i].active && attribs[i].mArrayEnabled && buffer)
+        {
+            StaticVertexBuffer *staticBuffer = buffer->getVertexBuffer();
+
+            if (staticBuffer && staticBuffer->size() != 0)
+            {
+                bool matchingAttributes = true;
+
+                for (int j = 0; j < MAX_VERTEX_ATTRIBS; j++)
+                {
+                    if (translated[j].active && attribs[j].mArrayEnabled && attribs[j].mBoundBuffer.get() == buffer)
+                    {
+                        if (staticBuffer->lookupAttribute(attribs[j]) == -1)
+                        {
+                            matchingAttributes = false;
+                            break;
+                        }
+                    }
+                }
+
+                if (!matchingAttributes && mStreamingBuffer)
+                {
+                    mStreamingBuffer->addRequiredSpaceFor(staticBuffer);
+                    buffer->invalidateStaticData();
+                }
+            }
+        }
+    }
+
+    // Reserve the required space per used buffer
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    {
+        Buffer *buffer = attribs[i].mBoundBuffer.get();
+
+        if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
+        {
+            ArrayVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
+            ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer;
+
+            if (vertexBuffer)
+            {
+                vertexBuffer->reserveRequiredSpace();
+            }
+        }
+    }
+
+    // Perform the vertex data translations
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    {
+        if (translated[i].active)
+        {
+            Buffer *buffer = attribs[i].mBoundBuffer.get();
+
+            if (attribs[i].mArrayEnabled)
+            {
+                if (!buffer && attribs[i].mPointer == NULL)
+                {
+                    // This is an application error that would normally result in a crash, but we catch it and return an error
+                    ERR("An enabled vertex array has no buffer and no pointer.");
                     return GL_INVALID_OPERATION;
                 }
 
-                if (offset + inputStride * (start + count - 1) + elementSize > buffer->size())
+                const FormatConverter &converter = formatConverter(attribs[i]);
+
+                StaticVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
+                ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : static_cast<ArrayVertexBuffer*>(mStreamingBuffer);
+
+                UINT streamOffset = -1;
+
+                if (staticBuffer)
                 {
-                    mStreamBuffer->unmap();
-                    return GL_INVALID_OPERATION;
+                    streamOffset = staticBuffer->lookupAttribute(attribs[i]);
+
+                    if (streamOffset == -1)
+                    {
+                        // Convert the entire buffer
+                        int totalCount = buffer->size() / attribs[i].stride();
+                        int startIndex = attribs[i].mOffset / attribs[i].stride();
+
+                        streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i]);
+                    }
+
+                    if (streamOffset != -1)
+                    {
+                        streamOffset += (start + attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize;
+                    }
+                }
+                else
+                {
+                    streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
                 }
 
-                input = static_cast<const char*>(buffer->data()) + offset;
+                if (streamOffset == -1)
+                {
+                    return GL_OUT_OF_MEMORY;
+                }
+
+                translated[i].vertexBuffer = vertexBuffer->getBuffer();
+                translated[i].type = converter.d3dDeclType;
+                translated[i].stride = converter.outputElementSize;
+                translated[i].offset = streamOffset;
             }
             else
             {
-                input = attribs[i].mPointer;
-            }
+                if (mDirtyCurrentValue[i])
+                {
+                    delete mCurrentValueBuffer[i];
+                    mCurrentValueBuffer[i] = new ConstantVertexBuffer(mDevice, attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
+                    mDirtyCurrentValue[i] = false;
+                }
 
-            input = static_cast<const char*>(input) + inputStride * start;
+                translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer();
 
-            if (formatConverter.identity && inputStride == elementSize)
-            {
-                memcpy(output, input, count * inputStride);
+                translated[i].type = D3DDECLTYPE_FLOAT4;
+                translated[i].stride = 0;
+                translated[i].offset = 0;
             }
-            else
-            {
-                formatConverter.convertArray(input, inputStride, count, output);
-            }
-
-            mStreamBuffer->unmap();
         }
     }
 
-    if (usesCurrentValues)
-    {
-        processNonArrayAttributes(attribs, activeAttribs, translated, count);
-    }
-
     return GL_NO_ERROR;
 }
 
-std::size_t VertexDataManager::typeSize(GLenum type) const
+std::size_t VertexDataManager::spaceRequired(const VertexAttribute &attrib, std::size_t count) const
+{
+    return formatConverter(attrib).outputElementSize * count;
+}
+
+// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
+//
+// BYTE                 SHORT (Cast)
+// BYTE-norm            FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
+// UNSIGNED_BYTE        UBYTE4 (Identity) or SHORT (Cast)
+// UNSIGNED_BYTE-norm   UBYTE4N (Identity) or FLOAT (Normalize)
+// SHORT                SHORT (Identity)
+// SHORT-norm           SHORT-norm (Identity) or FLOAT (Normalize)
+// UNSIGNED_SHORT       FLOAT (Cast)
+// UNSIGNED_SHORT-norm  USHORT-norm (Identity) or FLOAT (Normalize)
+// FIXED (not in WebGL) FLOAT (FixedToFloat)
+// FLOAT                FLOAT (Identity)
+
+// GLToCType maps from GL type (as GLenum) to the C typedef. 
+template <GLenum GLType> struct GLToCType { };
+
+template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; };
+template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; };
+template <> struct GLToCType<GL_SHORT> { typedef GLshort type; };
+template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; };
+template <> struct GLToCType<GL_FIXED> { typedef GLuint type; };
+template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; };
+
+// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
+enum D3DVertexType
+{
+    D3DVT_FLOAT,
+    D3DVT_SHORT,
+    D3DVT_SHORT_NORM,
+    D3DVT_UBYTE,
+    D3DVT_UBYTE_NORM,
+    D3DVT_USHORT_NORM
+};
+
+// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
+template <unsigned int D3DType> struct D3DToCType { };
+
+template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
+template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
+template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
+template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
+template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
+template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
+
+// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
+template <unsigned int type, int size>
+struct WidenRule
+{
+};
+
+template <int size> struct WidenRule<D3DVT_FLOAT, size>          : gl::NoWiden<size> { };
+template <int size> struct WidenRule<D3DVT_SHORT, size>          : gl::WidenToEven<size> { };
+template <int size> struct WidenRule<D3DVT_SHORT_NORM, size>     : gl::WidenToEven<size> { };
+template <int size> struct WidenRule<D3DVT_UBYTE, size>          : gl::WidenToFour<size> { };
+template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size>     : gl::WidenToFour<size> { };
+template <int size> struct WidenRule<D3DVT_USHORT_NORM, size>    : gl::WidenToEven<size> { };
+
+// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
+template <unsigned int d3dtype, int size>
+struct VertexTypeFlags
+{
+};
+
+template <unsigned int capflag, unsigned int declflag>
+struct VertexTypeFlagsHelper
+{
+    enum { capflag = capflag };
+    enum { declflag = declflag };
+};
+
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
+template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
+template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
+template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
+template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
+
+
+// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
+template <GLenum GLtype, bool normalized>
+struct VertexTypeMapping
+{
+};
+
+template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
+struct VertexTypeMappingBase
+{
+    enum { preferred = Preferred };
+    enum { fallback = Fallback };
+};
+
+template <> struct VertexTypeMapping<GL_BYTE, false>                        : VertexTypeMappingBase<D3DVT_SHORT> { };                       // Cast
+template <> struct VertexTypeMapping<GL_BYTE, true>                         : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Normalize
+template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false>               : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { };          // Identity, Cast
+template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true>                : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { };     // Identity, Normalize
+template <> struct VertexTypeMapping<GL_SHORT, false>                       : VertexTypeMappingBase<D3DVT_SHORT> { };                       // Identity
+template <> struct VertexTypeMapping<GL_SHORT, true>                        : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { };     // Cast, Normalize
+template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false>              : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Cast
+template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true>               : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { };    // Cast, Normalize
+template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized>   : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // FixedToFloat
+template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized>   : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Identity
+
+
+// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
+// The conversion rules themselves are defined in vertexconversion.h.
+
+// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
+template <GLenum fromType, bool normalized, unsigned int toType>
+struct ConversionRule : gl::Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type>
+{
+};
+
+// All conversions from normalized types to float use the Normalize operator.
+template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : gl::Normalize<typename GLToCType<fromType>::type> { };
+
+// Use a full specialisation for this so that it preferentially matches ahead of the generic normalize-to-float rules.
+template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { };
+template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { };
+
+// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
+// whether it is normalized or not.
+template <class T, bool normalized>
+struct DefaultVertexValuesStage2
+{
+};
+
+template <class T> struct DefaultVertexValuesStage2<T, true>  : gl::NormalizedDefaultValues<T> { };
+template <class T> struct DefaultVertexValuesStage2<T, false> : gl::SimpleDefaultValues<T> { };
+
+// Work out the default value rule for a D3D type (expressed as the C type) and 
+template <class T, bool normalized>
+struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized>
+{
+};
+
+template <bool normalized> struct DefaultVertexValues<float, normalized> : gl::SimpleDefaultValues<float> { };
+
+// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
+// The fallback conversion produces an output that all D3D9 devices must support.
+template <class T> struct UsePreferred { enum { type = T::preferred }; };
+template <class T> struct UseFallback { enum { type = T::fallback }; };
+
+// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
+// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
+// and the D3DDECLTYPE member needed for the vertex declaration in declflag.
+template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
+struct Converter
+    : gl::VertexDataConverter<typename GLToCType<fromType>::type,
+                              WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
+                              ConversionRule<fromType,
+                                             normalized,
+                                             PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
+                              DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
+{
+private:
+    enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
+    enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
+
+public:
+    enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
+    enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
+};
+
+// Initialise a TranslationInfo
+#define TRANSLATION(type, norm, size, preferred)                                    \
+    {                                                                               \
+        Converter<type, norm, size, preferred>::identity,                           \
+        Converter<type, norm, size, preferred>::finalSize,                          \
+        Converter<type, norm, size, preferred>::convertArray,                       \
+        static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag)  \
+    }
+
+#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size)    \
+    {                                                       \
+        Converter<type, norm, size, UsePreferred>::capflag, \
+        TRANSLATION(type, norm, size, UsePreferred),        \
+        TRANSLATION(type, norm, size, UseFallback)          \
+    }
+
+#define TRANSLATIONS_FOR_TYPE(type)                                                                                                                                                                         \
+    {                                                                                                                                                                                                       \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) },     \
+    }
+
+const VertexDataManager::TranslationDescription VertexDataManager::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
+{
+    TRANSLATIONS_FOR_TYPE(GL_BYTE),
+    TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
+    TRANSLATIONS_FOR_TYPE(GL_SHORT),
+    TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
+    TRANSLATIONS_FOR_TYPE(GL_FIXED),
+    TRANSLATIONS_FOR_TYPE(GL_FLOAT)
+};
+
+void VertexDataManager::checkVertexCaps(DWORD declTypes)
+{
+    for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
+    {
+        for (unsigned int j = 0; j < 2; j++)
+        {
+            for (unsigned int k = 0; k < 4; k++)
+            {
+                if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0)
+                {
+                    mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
+                }
+                else
+                {
+                    mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
+                }
+            }
+        }
+    }
+}
+
+// This is used to index mAttributeTypes and mPossibleTranslations.
+unsigned int VertexDataManager::typeIndex(GLenum type) const
 {
     switch (type)
     {
-      case GL_BYTE: case GL_UNSIGNED_BYTE: return sizeof(GLbyte);
-      case GL_SHORT: case GL_UNSIGNED_SHORT: return sizeof(GLshort);
-      case GL_FIXED: return sizeof(GLfixed);
-      case GL_FLOAT: return sizeof(GLfloat);
-      default: UNREACHABLE(); return sizeof(GLfloat);
+      case GL_BYTE: return 0;
+      case GL_UNSIGNED_BYTE: return 1;
+      case GL_SHORT: return 2;
+      case GL_UNSIGNED_SHORT: return 3;
+      case GL_FIXED: return 4;
+      case GL_FLOAT: return 5;
+
+      default: UNREACHABLE(); return 5;
     }
 }
 
-std::size_t VertexDataManager::interpretGlStride(const AttributeState &attrib) const
+void VertexDataManager::setupAttributes(const TranslatedAttribute *attributes)
 {
-    return attrib.mStride ? attrib.mStride : typeSize(attrib.mType) * attrib.mSize;
-}
+    D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS];
+    D3DVERTEXELEMENT9 *element = &elements[0];
 
-// Round up x (>=0) to the next multiple of multiple (>0).
-// 0 rounds up to 0.
-std::size_t VertexDataManager::roundUp(std::size_t x, std::size_t multiple) const
-{
-    ASSERT(x >= 0);
-    ASSERT(multiple > 0);
-
-    std::size_t remainder = x % multiple;
-    if (remainder != 0)
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
     {
-        return x + multiple - remainder;
-    }
-    else
-    {
-        return x;
-    }
-}
-
-std::size_t VertexDataManager::spaceRequired(const AttributeState &attrib, std::size_t maxVertex) const
-{
-    std::size_t size = mBackend->getFormatConverter(attrib.mType, attrib.mSize, attrib.mNormalized).outputVertexSize;
-    size *= maxVertex;
-
-    return roundUp(size, 4 * sizeof(GLfloat));
-}
-
-void VertexDataManager::processNonArrayAttributes(const AttributeState *attribs, const std::bitset<MAX_VERTEX_ATTRIBS> &activeAttribs, TranslatedAttribute *translated, std::size_t count)
-{
-    if (mDirtyCurrentValues)
-    {
-        std::size_t totalSize = 4 * sizeof(float) * MAX_VERTEX_ATTRIBS;
-
-        mCurrentValueBuffer->reserveSpace(totalSize);
-
-        float* currentValues = static_cast<float*>(mCurrentValueBuffer->map(totalSize, &mCurrentValueOffset));
-
-        for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+        if (attributes[i].active)
         {
-            // This assumes that the GL_FLOATx4 is supported by the back-end. (For D3D9, it is a mandatory format.)
-            currentValues[i*4+0] = attribs[i].mCurrentValue[0];
-            currentValues[i*4+1] = attribs[i].mCurrentValue[1];
-            currentValues[i*4+2] = attribs[i].mCurrentValue[2];
-            currentValues[i*4+3] = attribs[i].mCurrentValue[3];
+            mDevice->SetStreamSource(i, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
+
+            element->Stream = i;
+            element->Offset = 0;
+            element->Type = attributes[i].type;
+            element->Method = D3DDECLMETHOD_DEFAULT;
+            element->Usage = D3DDECLUSAGE_TEXCOORD;
+            element->UsageIndex = attributes[i].semanticIndex;
+            element++;
         }
-
-        mCurrentValueBuffer->unmap();
     }
 
-    for (std::size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    static const D3DVERTEXELEMENT9 end = D3DDECL_END();
+    *element = end;
+
+    IDirect3DVertexDeclaration9 *vertexDeclaration;
+    mDevice->CreateVertexDeclaration(elements, &vertexDeclaration);
+    mDevice->SetVertexDeclaration(vertexDeclaration);
+    vertexDeclaration->Release();
+}
+
+VertexBuffer::VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : mDevice(device), mVertexBuffer(NULL)
+{
+    if (size > 0)
     {
-        if (activeAttribs[i] && !attribs[i].mEnabled)
+        D3DPOOL pool = getDisplay()->getBufferPool(usageFlags);
+        HRESULT result = device->CreateVertexBuffer(size, usageFlags, 0, pool, &mVertexBuffer, NULL);
+        
+        if (FAILED(result))
         {
-            translated[i].nonArray = true;
-
-            translated[i].buffer = mCurrentValueBuffer;
-
-            translated[i].type = GL_FLOAT;
-            translated[i].size = 4;
-            translated[i].normalized = false;
-            translated[i].stride = 0;
-            translated[i].offset = mCurrentValueOffset + 4 * sizeof(float) * i;
+            ERR("Out of memory allocating a vertex buffer of size %lu.", size);
         }
     }
 }
 
+VertexBuffer::~VertexBuffer()
+{
+    if (mVertexBuffer)
+    {
+        mVertexBuffer->Release();
+    }
+}
+
+void VertexBuffer::unmap()
+{
+    if (mVertexBuffer)
+    {
+        mVertexBuffer->Unlock();
+    }
+}
+
+IDirect3DVertexBuffer9 *VertexBuffer::getBuffer() const
+{
+    return mVertexBuffer;
+}
+
+ConstantVertexBuffer::ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w) : VertexBuffer(device, 4 * sizeof(float), D3DUSAGE_WRITEONLY)
+{
+    void *buffer = NULL;
+
+    if (mVertexBuffer)
+    {
+        HRESULT result = mVertexBuffer->Lock(0, 0, &buffer, 0);
+     
+        if (FAILED(result))
+        {
+            ERR("Lock failed with error 0x%08x", result);
+        }
+    }
+
+    if (buffer)
+    {
+        float *vector = (float*)buffer;
+
+        vector[0] = x;
+        vector[1] = y;
+        vector[2] = z;
+        vector[3] = w;
+
+        mVertexBuffer->Unlock();
+    }
+}
+
+ConstantVertexBuffer::~ConstantVertexBuffer()
+{
+}
+
+ArrayVertexBuffer::ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : VertexBuffer(device, size, usageFlags)
+{
+    mBufferSize = size;
+    mWritePosition = 0;
+    mRequiredSpace = 0;
+}
+
+ArrayVertexBuffer::~ArrayVertexBuffer()
+{
+}
+
+void ArrayVertexBuffer::addRequiredSpace(UINT requiredSpace)
+{
+    mRequiredSpace += requiredSpace;
+}
+
+void ArrayVertexBuffer::addRequiredSpaceFor(ArrayVertexBuffer *buffer)
+{
+    mRequiredSpace += buffer->mRequiredSpace;
+}
+
+StreamingVertexBuffer::StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize) : ArrayVertexBuffer(device, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)
+{
+}
+
+StreamingVertexBuffer::~StreamingVertexBuffer()
+{
+}
+
+void *StreamingVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *offset)
+{
+    void *mapPtr = NULL;
+
+    if (mVertexBuffer)
+    {
+        HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
+        
+        if (FAILED(result))
+        {
+            ERR("Lock failed with error 0x%08x", result);
+            return NULL;
+        }
+
+        *offset = mWritePosition;
+        mWritePosition += requiredSpace;
+    }
+
+    return mapPtr;
+}
+
+void StreamingVertexBuffer::reserveRequiredSpace()
+{
+    if (mRequiredSpace > mBufferSize)
+    {
+        if (mVertexBuffer)
+        {
+            mVertexBuffer->Release();
+            mVertexBuffer = NULL;
+        }
+
+        mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
+
+        D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
+        HRESULT result = mDevice->CreateVertexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
+    
+        if (FAILED(result))
+        {
+            ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
+        }
+
+        mWritePosition = 0;
+    }
+    else if (mWritePosition + mRequiredSpace > mBufferSize)   // Recycle
+    {
+        if (mVertexBuffer)
+        {
+            void *dummy;
+            mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+            mVertexBuffer->Unlock();
+        }
+
+        mWritePosition = 0;
+    }
+
+    mRequiredSpace = 0;
+}
+
+StaticVertexBuffer::StaticVertexBuffer(IDirect3DDevice9 *device) : ArrayVertexBuffer(device, 0, D3DUSAGE_WRITEONLY)
+{
+}
+
+StaticVertexBuffer::~StaticVertexBuffer()
+{
+}
+
+void *StaticVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, UINT *streamOffset)
+{
+    void *mapPtr = NULL;
+
+    if (mVertexBuffer)
+    {
+        HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, 0);
+        
+        if (FAILED(result))
+        {
+            ERR("Lock failed with error 0x%08x", result);
+            return NULL;
+        }
+
+        int attributeOffset = attribute.mOffset % attribute.stride();
+        VertexElement element = {attribute.mType, attribute.mSize, attribute.mNormalized, attributeOffset, mWritePosition};
+        mCache.push_back(element);
+
+        *streamOffset = mWritePosition;
+        mWritePosition += requiredSpace;
+    }
+
+    return mapPtr;
+}
+
+void StaticVertexBuffer::reserveRequiredSpace()
+{
+    if (!mVertexBuffer && mBufferSize == 0)
+    {
+        D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
+        HRESULT result = mDevice->CreateVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
+    
+        if (FAILED(result))
+        {
+            ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace);
+        }
+
+        mBufferSize = mRequiredSpace;
+    }
+    else if (mVertexBuffer && mBufferSize >= mRequiredSpace)
+    {
+        // Already allocated
+    }
+    else UNREACHABLE();   // Static vertex buffers can't be resized
+
+    mRequiredSpace = 0;
+}
+
+UINT StaticVertexBuffer::lookupAttribute(const VertexAttribute &attribute)
+{
+    for (unsigned int element = 0; element < mCache.size(); element++)
+    {
+        if (mCache[element].type == attribute.mType &&  mCache[element].size == attribute.mSize && mCache[element].normalized == attribute.mNormalized)
+        {
+            if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
+            {
+                return mCache[element].streamOffset;
+            }
+        }
+    }
+
+    return -1;
+}
+
+const VertexDataManager::FormatConverter &VertexDataManager::formatConverter(const VertexAttribute &attribute) const
+{
+    return mAttributeTypes[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1];
+}
 }
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h
index 04900b8..257f2c3 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h
@@ -10,7 +10,7 @@
 #ifndef LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
 #define LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
 
-#include <bitset>
+#include <vector>
 #include <cstddef>
 
 #define GL_APICALL
@@ -21,44 +21,148 @@
 namespace gl
 {
 
-class Buffer;
-class BufferBackEnd;
-class TranslatedVertexBuffer;
-struct TranslatedAttribute;
-struct FormatConverter;
-struct TranslatedIndexData;
+struct TranslatedAttribute
+{
+    bool active;
+
+    D3DDECLTYPE type;
+    UINT offset;
+    UINT stride;   // 0 means not to advance the read pointer at all
+    UINT semanticIndex;
+
+    IDirect3DVertexBuffer9 *vertexBuffer;
+};
+
+class VertexBuffer
+{
+  public:
+    VertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
+    virtual ~VertexBuffer();
+
+    void unmap();
+
+    IDirect3DVertexBuffer9 *getBuffer() const;
+
+  protected:
+    IDirect3DDevice9 *const mDevice;
+    IDirect3DVertexBuffer9 *mVertexBuffer;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
+};
+
+class ConstantVertexBuffer : public VertexBuffer
+{
+  public:
+    ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w);
+    ~ConstantVertexBuffer();
+};
+
+class ArrayVertexBuffer : public VertexBuffer
+{
+  public:
+    ArrayVertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
+    ~ArrayVertexBuffer();
+
+    UINT size() const { return mBufferSize; }
+    virtual void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset) = 0;
+    virtual void reserveRequiredSpace() = 0;
+    void addRequiredSpace(UINT requiredSpace);
+    void addRequiredSpaceFor(ArrayVertexBuffer *buffer);
+
+  protected:
+    UINT mBufferSize;
+    UINT mWritePosition;
+    UINT mRequiredSpace;
+};
+
+class StreamingVertexBuffer : public ArrayVertexBuffer
+{
+  public:
+    StreamingVertexBuffer(IDirect3DDevice9 *device, UINT initialSize);
+    ~StreamingVertexBuffer();
+
+    void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
+    void reserveRequiredSpace();
+};
+
+class StaticVertexBuffer : public ArrayVertexBuffer
+{
+  public:
+    explicit StaticVertexBuffer(IDirect3DDevice9 *device);
+    ~StaticVertexBuffer();
+
+    void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
+    void reserveRequiredSpace();
+
+    UINT lookupAttribute(const VertexAttribute &attribute);   // Returns the offset into the vertex buffer, or -1 if not found
+
+  private:
+    struct VertexElement
+    {
+        GLenum type;
+        GLint size;
+        bool normalized;
+        int attributeOffset;
+
+        UINT streamOffset;
+    };
+
+    std::vector<VertexElement> mCache;
+};
 
 class VertexDataManager
 {
   public:
-    VertexDataManager(Context *context, BufferBackEnd *backend);
-    ~VertexDataManager();
+    VertexDataManager(Context *context, IDirect3DDevice9 *backend);
+    virtual ~VertexDataManager();
 
-    void dirtyCurrentValues() { mDirtyCurrentValues = true; }
+    void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
 
-    GLenum preRenderValidate(GLint start,
-                             GLsizei count,
-                             TranslatedAttribute *outAttribs);
+    void setupAttributes(const TranslatedAttribute *attributes);
+    GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
 
   private:
-    std::bitset<MAX_VERTEX_ATTRIBS> getActiveAttribs() const;
+    DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
 
-    void processNonArrayAttributes(const AttributeState *attribs, const std::bitset<MAX_VERTEX_ATTRIBS> &activeAttribs, TranslatedAttribute *translated, std::size_t count);
+    UINT spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
+    UINT writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
 
-    std::size_t typeSize(GLenum type) const;
-    std::size_t interpretGlStride(const AttributeState &attrib) const;
+    Context *const mContext;
+    IDirect3DDevice9 *const mDevice;
 
-    std::size_t roundUp(std::size_t x, std::size_t multiple) const;
-    std::size_t spaceRequired(const AttributeState &attrib, std::size_t maxVertex) const;
+    StreamingVertexBuffer *mStreamingBuffer;
 
-    Context *mContext;
-    BufferBackEnd *mBackend;
+    bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
+    ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
 
-    TranslatedVertexBuffer *mStreamBuffer;
+    // Attribute format conversion
+    struct FormatConverter
+    {
+        bool identity;
+        std::size_t outputElementSize;
+        void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
+        D3DDECLTYPE d3dDeclType;
+    };
 
-    bool mDirtyCurrentValues;
-    std::size_t mCurrentValueOffset;            // Offset within mCurrentValueBuffer that the current attribute values were last loaded at.
-    TranslatedVertexBuffer *mCurrentValueBuffer;
+    enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
+
+    FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];   // [GL types as enumerated by typeIndex()][normalized][size - 1]
+
+    struct TranslationDescription
+    {
+        DWORD capsFlag;
+        FormatConverter preferredConversion;
+        FormatConverter fallbackConversion;
+    };
+
+    // This table is used to generate mAttributeTypes.
+    static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
+
+    void checkVertexCaps(DWORD declTypes);
+
+    unsigned int typeIndex(GLenum type) const;
+    const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
 };
 
 }
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.cpp
deleted file mode 100644
index 3f5e283..0000000
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// geometry/backend.h: Abstract classes BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer
-// that must be implemented by any API-specific implementation of ANGLE.
-
-#include "libGLESv2/geometry/backend.h"
-
-#include "common/debug.h"
-
-namespace gl
-{
-
-void *TranslatedBuffer::map(std::size_t requiredSpace, std::size_t *offset)
-{
-    ASSERT(requiredSpace <= mBufferSize);
-
-    reserveSpace(requiredSpace);
-
-    *offset = mCurrentPoint;
-    mCurrentPoint += requiredSpace;
-
-    return streamingMap(*offset, requiredSpace);
-}
-
-void TranslatedBuffer::reserveSpace(std::size_t requiredSpace)
-{
-    if (mCurrentPoint + requiredSpace > mBufferSize)
-    {
-        recycle();
-        mCurrentPoint = 0;
-    }
-}
-
-}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.h b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.h
deleted file mode 100644
index d18a908..0000000
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// geometry/backend.h: Abstract classes BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer
-// that must be implemented by any API-specific implementation of ANGLE.
-
-#ifndef LIBGLESV2_GEOMETRY_BACKEND_H_
-#define LIBGLESV2_GEOMETRY_BACKEND_H_
-
-#include <cstddef>
-
-#define GL_APICALL
-#include <GLES2/gl2.h>
-
-#include "libGLESv2/Context.h"
-
-namespace gl
-{
-class TranslatedVertexBuffer;
-class TranslatedIndexBuffer;
-
-struct FormatConverter
-{
-    bool identity;
-    std::size_t outputVertexSize;
-    void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
-};
-
-struct TranslatedAttribute
-{
-    bool enabled;
-    bool nonArray;
-
-    // These are the original untranslated values. (Or just have some sort of BufferBackEnd::TranslatedTypeKey.)
-    GLenum type;
-    std::size_t size;
-    bool normalized;
-
-    std::size_t offset;
-
-    std::size_t stride; // 0 means not to advance the read pointer at all
-
-    std::size_t semanticIndex;
-
-    TranslatedVertexBuffer *buffer;
-};
-
-class BufferBackEnd
-{
-  public:
-    virtual ~BufferBackEnd() { }
-
-    virtual bool supportIntIndices() = 0;
-
-    virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size) = 0;
-    virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size) = 0;
-    virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type) = 0;
-    virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize) = 0;
-
-    // For an identity-mappable stream, verify that the stride and offset are okay.
-    virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const = 0;
-
-    virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo) = 0;
-    virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes) = 0;
-};
-
-class TranslatedBuffer
-{
-  public:
-    explicit TranslatedBuffer(std::size_t size) : mBufferSize(size), mCurrentPoint(0) { }
-    virtual ~TranslatedBuffer() { }
-
-    std::size_t size() const { return mBufferSize; }
-
-    virtual void *map() = 0;
-    virtual void unmap() = 0;
-
-    void reserveSpace(std::size_t requiredSpace);
-
-    void *map(std::size_t requiredSpace, std::size_t *offset);
-
-  protected:
-    virtual void recycle() = 0;
-    virtual void *streamingMap(std::size_t offset, std::size_t size) = 0;
-
-  private:
-    std::size_t mBufferSize;
-    std::size_t mCurrentPoint;
-
-    DISALLOW_COPY_AND_ASSIGN(TranslatedBuffer);
-};
-
-class TranslatedVertexBuffer : public TranslatedBuffer
-{
-  public:
-    explicit TranslatedVertexBuffer(std::size_t size) : TranslatedBuffer(size) { }
-};
-
-class TranslatedIndexBuffer : public TranslatedBuffer
-{
-  public:
-    explicit TranslatedIndexBuffer(std::size_t size) : TranslatedBuffer(size) { }
-};
-
-}
-
-#endif   // LIBGLESV2_GEOMETRY_BACKEND_H_
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.cpp
deleted file mode 100644
index e51befb..0000000
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// geometry/dx9.h: Direct3D 9-based implementation of BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer.
-
-#include "libGLESv2/geometry/dx9.h"
-
-#include <cstddef>
-
-#define GL_APICALL
-#include <GLES2/gl2.h>
-
-#include "common/debug.h"
-
-#include "libGLESv2/Context.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/geometry/vertexconversion.h"
-#include "libGLESv2/geometry/IndexDataManager.h"
-
-namespace
-{
-// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
-//
-// BYTE                 SHORT (Cast)
-// BYTE-norm            FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
-// UNSIGNED_BYTE        UBYTE4 (Identity) or SHORT (Cast)
-// UNSIGNED_BYTE-norm   UBYTE4N (Identity) or FLOAT (Normalize)
-// SHORT                SHORT (Identity)
-// SHORT-norm           SHORT-norm (Identity) or FLOAT (Normalize)
-// UNSIGNED_SHORT       FLOAT (Cast)
-// UNSIGNED_SHORT-norm  USHORT-norm (Identity) or FLOAT (Normalize)
-// FIXED (not in WebGL) FLOAT (FixedToFloat)
-// FLOAT                FLOAT (Identity)
-
-// GLToCType maps from GL type (as GLenum) to the C typedef. 
-template <GLenum GLType> struct GLToCType { };
-
-template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; };
-template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; };
-template <> struct GLToCType<GL_SHORT> { typedef GLshort type; };
-template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; };
-template <> struct GLToCType<GL_FIXED> { typedef GLuint type; };
-template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; };
-
-// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
-enum D3DVertexType
-{
-    D3DVT_FLOAT,
-    D3DVT_SHORT,
-    D3DVT_SHORT_NORM,
-    D3DVT_UBYTE,
-    D3DVT_UBYTE_NORM,
-    D3DVT_USHORT_NORM
-};
-
-// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
-template <unsigned int D3DType> struct D3DToCType { };
-
-template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
-template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
-template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
-template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
-template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
-template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
-
-// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
-template <unsigned int type, int size>
-struct WidenRule
-{
-};
-
-template <int size> struct WidenRule<D3DVT_FLOAT, size>          : gl::NoWiden<size> { };
-template <int size> struct WidenRule<D3DVT_SHORT, size>          : gl::WidenToEven<size> { };
-template <int size> struct WidenRule<D3DVT_SHORT_NORM, size>     : gl::WidenToEven<size> { };
-template <int size> struct WidenRule<D3DVT_UBYTE, size>          : gl::WidenToFour<size> { };
-template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size>     : gl::WidenToFour<size> { };
-template <int size> struct WidenRule<D3DVT_USHORT_NORM, size>    : gl::WidenToEven<size> { };
-
-// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
-template <unsigned int d3dtype, int size>
-struct VertexTypeFlags
-{
-};
-
-template <unsigned int capflag, unsigned int declflag>
-struct VertexTypeFlagsHelper
-{
-    enum { capflag = capflag };
-    enum { declflag = declflag };
-};
-
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
-template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
-template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
-template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
-template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
-
-
-// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
-template <GLenum GLtype, bool normalized>
-struct VertexTypeMapping
-{
-};
-
-template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
-struct VertexTypeMappingBase
-{
-    enum { preferred = Preferred };
-    enum { fallback = Fallback };
-};
-
-template <> struct VertexTypeMapping<GL_BYTE, false>                        : VertexTypeMappingBase<D3DVT_SHORT> { };                       // Cast
-template <> struct VertexTypeMapping<GL_BYTE, true>                         : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Normalize
-template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false>               : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { };          // Identity, Cast
-template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true>                : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { };     // Identity, Normalize
-template <> struct VertexTypeMapping<GL_SHORT, false>                       : VertexTypeMappingBase<D3DVT_SHORT> { };                       // Identity
-template <> struct VertexTypeMapping<GL_SHORT, true>                        : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { };     // Cast, Normalize
-template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false>              : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Cast
-template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true>               : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { };    // Cast, Normalize
-template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized>   : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // FixedToFloat
-template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized>   : VertexTypeMappingBase<D3DVT_FLOAT> { };                       // Identity
-
-
-// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
-// The conversion rules themselves are defined in vertexconversion.h.
-
-// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
-template <GLenum fromType, bool normalized, unsigned int toType>
-struct ConversionRule : gl::Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type>
-{
-};
-
-// All conversions from normalized types to float use the Normalize operator.
-template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : gl::Normalize<typename GLToCType<fromType>::type> { };
-
-// Use a full specialisation for this so that it preferentially matches ahead of the generic normalize-to-float rules.
-template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { };
-template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { };
-
-// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
-// whether it is normalized or not.
-template <class T, bool normalized>
-struct DefaultVertexValuesStage2
-{
-};
-
-template <class T> struct DefaultVertexValuesStage2<T, true>  : gl::NormalizedDefaultValues<T> { };
-template <class T> struct DefaultVertexValuesStage2<T, false> : gl::SimpleDefaultValues<T> { };
-
-// Work out the default value rule for a D3D type (expressed as the C type) and 
-template <class T, bool normalized>
-struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized>
-{
-};
-
-template <bool normalized> struct DefaultVertexValues<float, normalized> : gl::SimpleDefaultValues<float> { };
-
-// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
-// The fallback conversion produces an output that all D3D9 devices must support.
-template <class T> struct UsePreferred { enum { type = T::preferred }; };
-template <class T> struct UseFallback { enum { type = T::fallback }; };
-
-// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
-// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
-// and the D3DDECLTYPE member needed for the vertex declaration in declflag.
-template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
-struct Converter
-    : gl::VertexDataConverter<typename GLToCType<fromType>::type,
-                              WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
-                              ConversionRule<fromType,
-                                             normalized,
-                                             PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
-                              DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
-{
-private:
-    enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
-    enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
-
-public:
-    enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
-    enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
-};
-
-}
-
-namespace gl
-{
-Dx9BackEnd::Dx9BackEnd(Context *context, IDirect3DDevice9 *d3ddevice)
-    : mDevice(d3ddevice)
-{
-    mDevice->AddRef();
-
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
-    {
-        mAppliedAttribEnabled[i] = true;
-        mStreamFrequency[i] = STREAM_FREQUENCY_UNINSTANCED;
-    }
-
-    mStreamFrequency[MAX_VERTEX_ATTRIBS] = STREAM_FREQUENCY_UNINSTANCED;
-
-    D3DCAPS9 caps = context->getDeviceCaps();
-
-    IDirect3D9 *d3dObject;
-    mDevice->GetDirect3D(&d3dObject);
-
-    D3DADAPTER_IDENTIFIER9 ident;
-    d3dObject->GetAdapterIdentifier(caps.AdapterOrdinal, 0, &ident);
-    d3dObject->Release();
-
-    // Instancing is mandatory for all HW with SM3 vertex shaders, but avoid hardware where it does not work.
-    mUseInstancingForStrideZero = (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0) && ident.VendorId != 0x8086);
-    mSupportIntIndices = (caps.MaxVertexIndex >= (1 << 16));
-
-    checkVertexCaps(caps.DeclTypes);
-}
-
-Dx9BackEnd::~Dx9BackEnd()
-{
-    mDevice->Release();
-}
-
-bool Dx9BackEnd::supportIntIndices()
-{
-    return mSupportIntIndices;
-}
-
-// Initialise a TranslationInfo
-#define TRANSLATION(type, norm, size, preferred)                                    \
-    {                                                                               \
-        {                                                                           \
-            Converter<type, norm, size, preferred>::identity,                       \
-            Converter<type, norm, size, preferred>::finalSize,                      \
-            Converter<type, norm, size, preferred>::convertArray,                   \
-        },                                                                          \
-        static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag)  \
-    }
-
-#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size)    \
-    {                                                       \
-        Converter<type, norm, size, UsePreferred>::capflag, \
-        TRANSLATION(type, norm, size, UsePreferred),        \
-        TRANSLATION(type, norm, size, UseFallback)          \
-    }
-
-#define TRANSLATIONS_FOR_TYPE(type)                                                                                                                                                                         \
-    {                                                                                                                                                                                                       \
-        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
-        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) },     \
-    }
-
-const Dx9BackEnd::TranslationDescription Dx9BackEnd::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
-{
-    TRANSLATIONS_FOR_TYPE(GL_BYTE),
-    TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
-    TRANSLATIONS_FOR_TYPE(GL_SHORT),
-    TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
-    TRANSLATIONS_FOR_TYPE(GL_FIXED),
-    TRANSLATIONS_FOR_TYPE(GL_FLOAT)
-};
-
-void Dx9BackEnd::checkVertexCaps(DWORD declTypes)
-{
-    for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
-    {
-        for (unsigned int j = 0; j < 2; j++)
-        {
-            for (unsigned int k = 0; k < 4; k++)
-            {
-                if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0)
-                {
-                    mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
-                }
-                else
-                {
-                    mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
-                }
-            }
-        }
-    }
-}
-
-TranslatedVertexBuffer *Dx9BackEnd::createVertexBuffer(std::size_t size)
-{
-    return new Dx9VertexBuffer(mDevice, size);
-}
-
-TranslatedVertexBuffer *Dx9BackEnd::createVertexBufferForStrideZero(std::size_t size)
-{
-    if (mUseInstancingForStrideZero)
-    {
-        return new Dx9VertexBuffer(mDevice, size);
-    }
-    else
-    {
-        return new Dx9VertexBufferZeroStrideWorkaround(mDevice, size);
-    }
-}
-
-TranslatedIndexBuffer *Dx9BackEnd::createIndexBuffer(std::size_t size, GLenum type)
-{
-    return new Dx9IndexBuffer(mDevice, size, type);
-}
-
-// This is used to index mAttributeTypes and mPossibleTranslations.
-unsigned int Dx9BackEnd::typeIndex(GLenum type) const
-{
-    switch (type)
-    {
-      case GL_BYTE: return 0;
-      case GL_UNSIGNED_BYTE: return 1;
-      case GL_SHORT: return 2;
-      case GL_UNSIGNED_SHORT: return 3;
-      case GL_FIXED: return 4;
-      case GL_FLOAT: return 5;
-
-      default: UNREACHABLE(); return 5;
-    }
-}
-
-FormatConverter Dx9BackEnd::getFormatConverter(GLenum type, std::size_t size, bool normalize)
-{
-    return mAttributeTypes[typeIndex(type)][normalize][size-1].formatConverter;
-}
-
-D3DDECLTYPE Dx9BackEnd::mapAttributeType(GLenum type, std::size_t size, bool normalize) const
-{
-    return mAttributeTypes[typeIndex(type)][normalize][size-1].d3dDeclType;
-}
-
-bool Dx9BackEnd::validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const
-{
-    // D3D9 requires the stream offset and stride to be a multiple of DWORD.
-    return (stride % sizeof(DWORD) == 0 && offset % sizeof(DWORD) == 0);
-}
-
-IDirect3DVertexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedVertexBuffer *vb) const
-{
-    return vb ? static_cast<Dx9VertexBuffer*>(vb)->getBuffer() : NULL;
-}
-
-IDirect3DIndexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedIndexBuffer *ib) const
-{
-    return ib ? static_cast<Dx9IndexBuffer*>(ib)->getBuffer() : NULL;
-}
-
-GLenum Dx9BackEnd::setupIndicesPreDraw(const TranslatedIndexData &indexInfo)
-{
-    mDevice->SetIndices(getDxBuffer(indexInfo.buffer));
-    return GL_NO_ERROR;
-}
-
-GLenum Dx9BackEnd::setupAttributesPreDraw(const TranslatedAttribute *attributes)
-{
-    HRESULT hr;
-
-    D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS+1];
-
-    D3DVERTEXELEMENT9 *nextElement = &elements[0];
-
-    for (BYTE i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (attributes[i].enabled)
-        {
-            nextElement->Stream = i + 1;    // Stream 0 is skipped because D3D does not permit it to be an instanced stream.
-            nextElement->Offset = 0;
-            nextElement->Type = static_cast<BYTE>(mapAttributeType(attributes[i].type, attributes[i].size, attributes[i].normalized));
-            nextElement->Method = D3DDECLMETHOD_DEFAULT;
-            nextElement->Usage = D3DDECLUSAGE_TEXCOORD;
-            nextElement->UsageIndex = attributes[i].semanticIndex;
-            nextElement++;
-        }
-    }
-
-    static const D3DVERTEXELEMENT9 end = D3DDECL_END();
-    *nextElement = end;
-
-    IDirect3DVertexDeclaration9* vertexDeclaration;
-    hr = mDevice->CreateVertexDeclaration(elements, &vertexDeclaration);
-    mDevice->SetVertexDeclaration(vertexDeclaration);
-    vertexDeclaration->Release();
-
-    mDevice->SetStreamSource(0, NULL, 0, 0);
-
-    bool nonArrayAttributes = false;
-
-    for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (attributes[i].enabled)
-        {
-            if (attributes[i].nonArray) nonArrayAttributes = true;
-
-            mDevice->SetStreamSource(i + 1, getDxBuffer(attributes[i].buffer), attributes[i].offset, attributes[i].stride);
-            if (!mAppliedAttribEnabled[i])
-            {
-                mAppliedAttribEnabled[i] = true;
-            }
-        }
-        else
-        {
-            if (mAppliedAttribEnabled[i])
-            {
-                mDevice->SetStreamSource(i + 1, 0, 0, 0);
-                mAppliedAttribEnabled[i] = false;
-            }
-        }
-    }
-
-    if (mUseInstancingForStrideZero)
-    {
-        // When there are no stride zero attributes, we disable instancing so that DrawPrimitive can be used.
-
-        if (nonArrayAttributes)
-        {
-            if (mStreamFrequency[0] != STREAM_FREQUENCY_INDEXED)
-            {
-                mStreamFrequency[0] = STREAM_FREQUENCY_INDEXED;
-                mDevice->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA | 1);
-            }
-
-            for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-            {
-                if (attributes[i].enabled)
-                {
-                    if (attributes[i].nonArray)
-                    {
-                        if (mStreamFrequency[i+1] != STREAM_FREQUENCY_INSTANCED)
-                        {
-                            mStreamFrequency[i+1] = STREAM_FREQUENCY_INSTANCED;
-                            mDevice->SetStreamSourceFreq(i + 1, D3DSTREAMSOURCE_INSTANCEDATA | 1);
-                        }
-                    }
-                    else
-                    {
-                        if (mStreamFrequency[i+1] != STREAM_FREQUENCY_INDEXED)
-                        {
-                            mStreamFrequency[i+1] = STREAM_FREQUENCY_INDEXED;
-                            mDevice->SetStreamSourceFreq(i + 1, D3DSTREAMSOURCE_INDEXEDDATA | 1);
-                        }
-                    }
-                }
-            }
-        }
-        else
-        {
-            for (size_t i = 0; i < MAX_VERTEX_ATTRIBS + 1; i++)
-            {
-                if (mStreamFrequency[i] != STREAM_FREQUENCY_UNINSTANCED)
-                {
-                    mStreamFrequency[i] = STREAM_FREQUENCY_UNINSTANCED;
-
-                    // This should not be needed, but otherwise there is a buggy driver that will leave instancing
-                    // enabled for the first draw after it has been turned off.
-                    mDevice->SetStreamSourceFreq(i, D3DSTREAMSOURCE_INDEXEDDATA | 1);
-
-                    mDevice->SetStreamSourceFreq(i, 1);
-                }
-            }
-        }
-    }
-
-    return GL_NO_ERROR;
-}
-
-Dx9BackEnd::Dx9VertexBuffer::Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size)
-    : TranslatedVertexBuffer(size)
-{
-    HRESULT hr = device->CreateVertexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
-    if (hr != S_OK)
-    {
-        ERR("Out of memory allocating a vertex buffer of size %lu.", size);
-        throw std::bad_alloc();
-    }
-}
-
-Dx9BackEnd::Dx9VertexBuffer::Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags)
-    : TranslatedVertexBuffer(size)
-{
-    HRESULT hr = device->CreateVertexBuffer(size, usageFlags, 0, D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
-    if (hr != S_OK)
-    {
-        ERR("Out of memory allocating a vertex buffer of size %lu.", size);
-        throw std::bad_alloc();
-    }
-}
-
-
-Dx9BackEnd::Dx9VertexBuffer::~Dx9VertexBuffer()
-{
-    mVertexBuffer->Release();
-}
-
-IDirect3DVertexBuffer9 *Dx9BackEnd::Dx9VertexBuffer::getBuffer() const
-{
-    return mVertexBuffer;
-}
-
-void *Dx9BackEnd::Dx9VertexBuffer::map()
-{
-    void *mapPtr;
-
-    mVertexBuffer->Lock(0, 0, &mapPtr, 0);
-
-    return mapPtr;
-}
-
-void Dx9BackEnd::Dx9VertexBuffer::unmap()
-{
-    mVertexBuffer->Unlock();
-}
-
-void Dx9BackEnd::Dx9VertexBuffer::recycle()
-{
-    void *dummy;
-    mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
-    mVertexBuffer->Unlock();
-}
-
-void *Dx9BackEnd::Dx9VertexBuffer::streamingMap(std::size_t offset, std::size_t size)
-{
-    void *mapPtr;
-
-    mVertexBuffer->Lock(offset, size, &mapPtr, D3DLOCK_NOOVERWRITE);
-
-    return mapPtr;
-}
-
-// Normally VBs are created with D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, but some hardware & drivers won't render
-// if any stride-zero streams are in D3DUSAGE_DYNAMIC VBs, so this provides a way to create such VBs with only D3DUSAGE_WRITEONLY set.
-// D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE are only available on D3DUSAGE_DYNAMIC VBs, so we override methods to avoid using these flags.
-Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::Dx9VertexBufferZeroStrideWorkaround(IDirect3DDevice9 *device, std::size_t size)
-    : Dx9VertexBuffer(device, size, D3DUSAGE_WRITEONLY)
-{
-}
-
-void Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::recycle()
-{
-}
-
-void *Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::streamingMap(std::size_t offset, std::size_t size)
-{
-    void *mapPtr;
-
-    getBuffer()->Lock(offset, size, &mapPtr, 0);
-
-    return mapPtr;
-}
-
-Dx9BackEnd::Dx9IndexBuffer::Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type)
-    : TranslatedIndexBuffer(size)
-{
-    ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT);
-
-    D3DFORMAT format = (type == GL_UNSIGNED_SHORT) ? D3DFMT_INDEX16 : D3DFMT_INDEX32;
-
-    HRESULT hr = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, D3DPOOL_DEFAULT, &mIndexBuffer, NULL);
-    if (hr != S_OK)
-    {
-        ERR("Out of memory allocating an index buffer of size %lu.", size);
-        throw std::bad_alloc();
-    }
-}
-
-Dx9BackEnd::Dx9IndexBuffer::~Dx9IndexBuffer()
-{
-    mIndexBuffer->Release();
-}
-
-IDirect3DIndexBuffer9*Dx9BackEnd::Dx9IndexBuffer::getBuffer() const
-{
-    return mIndexBuffer;
-}
-
-void *Dx9BackEnd::Dx9IndexBuffer::map()
-{
-    void *mapPtr;
-
-    mIndexBuffer->Lock(0, 0, &mapPtr, 0);
-
-    return mapPtr;
-}
-
-void Dx9BackEnd::Dx9IndexBuffer::unmap()
-{
-    mIndexBuffer->Unlock();
-}
-
-void Dx9BackEnd::Dx9IndexBuffer::recycle()
-{
-    void *dummy;
-    mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
-    mIndexBuffer->Unlock();
-}
-
-void *Dx9BackEnd::Dx9IndexBuffer::streamingMap(std::size_t offset, std::size_t size)
-{
-    void *mapPtr;
-
-    mIndexBuffer->Lock(offset, size, &mapPtr, D3DLOCK_NOOVERWRITE);
-
-    return mapPtr;
-}
-
-}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.h b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.h
deleted file mode 100644
index 6068dd6..0000000
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.h
+++ /dev/null
@@ -1,137 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// geometry/dx9.h: Direct3D 9-based implementation of BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer.
-
-#ifndef LIBGLESV2_GEOMETRY_DX9_H_
-#define LIBGLESV2_GEOMETRY_DX9_H_
-
-#include <d3d9.h>
-
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/geometry/backend.h"
-
-namespace gl
-{
-
-class Dx9BackEnd : public BufferBackEnd
-{
-  public:
-    explicit Dx9BackEnd(Context *context, IDirect3DDevice9 *d3ddevice);
-    ~Dx9BackEnd();
-
-    virtual bool supportIntIndices();
-
-    virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size);
-    virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size);
-    virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type);
-    virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize);
-
-    virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const;
-
-    virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo);
-    virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes);
-
-  private:
-    IDirect3DDevice9 *mDevice;
-
-    bool mUseInstancingForStrideZero;
-    bool mSupportIntIndices;
-
-    bool mAppliedAttribEnabled[MAX_VERTEX_ATTRIBS];
-
-    enum StreamFrequency
-    {
-        STREAM_FREQUENCY_UNINSTANCED = 0,
-        STREAM_FREQUENCY_INDEXED,
-        STREAM_FREQUENCY_INSTANCED
-    };
-
-    StreamFrequency mStreamFrequency[MAX_VERTEX_ATTRIBS+1];
-
-    struct TranslationInfo
-    {
-        FormatConverter formatConverter;
-        D3DDECLTYPE d3dDeclType;
-    };
-
-    enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
-
-    TranslationInfo mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size-1]
-
-    struct TranslationDescription
-    {
-        DWORD capsFlag;
-        TranslationInfo preferredConversion;
-        TranslationInfo fallbackConversion;
-    };
-
-    // This table is used to generate mAttributeTypes.
-    static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size-1]
-
-    void checkVertexCaps(DWORD declTypes);
-
-    unsigned int typeIndex(GLenum type) const;
-
-    class Dx9VertexBuffer : public TranslatedVertexBuffer
-    {
-      public:
-        Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size);
-        virtual ~Dx9VertexBuffer();
-
-        IDirect3DVertexBuffer9 *getBuffer() const;
-
-      protected:
-        Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags);
-
-        virtual void *map();
-        virtual void unmap();
-
-        virtual void recycle();
-        virtual void *streamingMap(std::size_t offset, std::size_t size);
-
-      private:
-        IDirect3DVertexBuffer9 *mVertexBuffer;
-    };
-
-    class Dx9VertexBufferZeroStrideWorkaround : public Dx9VertexBuffer
-    {
-      public:
-        Dx9VertexBufferZeroStrideWorkaround(IDirect3DDevice9 *device, std::size_t size);
-
-      protected:
-        virtual void recycle();
-        virtual void *streamingMap(std::size_t offset, std::size_t size);
-    };
-
-    class Dx9IndexBuffer : public TranslatedIndexBuffer
-    {
-      public:
-        Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type);
-        virtual ~Dx9IndexBuffer();
-
-        IDirect3DIndexBuffer9 *getBuffer() const;
-
-      protected:
-        virtual void *map();
-        virtual void unmap();
-
-        virtual void recycle();
-        virtual void *streamingMap(std::size_t offset, std::size_t size);
-
-      private:
-        IDirect3DIndexBuffer9 *mIndexBuffer;
-    };
-
-    IDirect3DVertexBuffer9 *getDxBuffer(TranslatedVertexBuffer *vb) const;
-    IDirect3DIndexBuffer9 *getDxBuffer(TranslatedIndexBuffer *ib) const;
-
-    D3DDECLTYPE mapAttributeType(GLenum type, std::size_t size, bool normalized) const;
-};
-
-}
-
-#endif   // LIBGLESV2_GEOMETRY_DX9_H_
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp
index 25d083b..543c0d2 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp
@@ -20,6 +20,7 @@
 #include "libGLESv2/utilities.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Context.h"
+#include "libGLESv2/Fence.h"
 #include "libGLESv2/Framebuffer.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/Renderbuffer.h"
@@ -736,7 +737,7 @@
 
     try
     {
-        if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
+        if (level < 0)
         {
             return error(GL_INVALID_VALUE);
         }
@@ -746,34 +747,6 @@
             return error(GL_INVALID_VALUE);
         }
 
-        switch (target)
-        {
-          case GL_TEXTURE_2D:
-            if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
-            {
-                return error(GL_INVALID_VALUE);
-            }
-            break;
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            if (width != height)
-            {
-                return error(GL_INVALID_VALUE);
-            }
-
-            if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
-            {
-                return error(GL_INVALID_VALUE);
-            }
-            break;
-          default:
-            return error(GL_INVALID_ENUM);
-        }
-
         switch (internalformat)
         {
           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
@@ -792,6 +765,41 @@
 
         if (context)
         {
+            if (level > context->getMaximumTextureLevel())
+            {
+                return error(GL_INVALID_VALUE);
+            }
+
+            switch (target)
+            {
+              case GL_TEXTURE_2D:
+                if (width > (context->getMaximumTextureDimension() >> level) ||
+                    height > (context->getMaximumTextureDimension() >> level))
+                {
+                    return error(GL_INVALID_VALUE);
+                }
+                break;
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+                if (width != height)
+                {
+                    return error(GL_INVALID_VALUE);
+                }
+
+                if (width > (context->getMaximumCubeTextureDimension() >> level) ||
+                    height > (context->getMaximumCubeTextureDimension() >> level))
+                {
+                    return error(GL_INVALID_VALUE);
+                }
+                break;
+              default:
+                return error(GL_INVALID_ENUM);
+            }
+
             if (!context->supportsCompressedTextures())
             {
                 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
@@ -859,7 +867,7 @@
             return error(GL_INVALID_ENUM);
         }
 
-        if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
+        if (level < 0)
         {
             return error(GL_INVALID_VALUE);
         }
@@ -888,6 +896,11 @@
 
         if (context)
         {
+            if (level > context->getMaximumTextureLevel())
+            {
+                return error(GL_INVALID_VALUE);
+            }
+
             if (!context->supportsCompressedTextures())
             {
                 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
@@ -978,48 +991,6 @@
             return error(GL_INVALID_VALUE);
         }
 
-        switch (target)
-        {
-          case GL_TEXTURE_2D:
-            if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
-            {
-                return error(GL_INVALID_VALUE);
-            }
-            break;
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            if (width != height)
-            {
-                return error(GL_INVALID_VALUE);
-            }
-
-            if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
-            {
-                return error(GL_INVALID_VALUE);
-            }
-            break;
-          default:
-            return error(GL_INVALID_ENUM);
-        }
-
-        switch (internalformat)
-        {
-          case GL_ALPHA:
-          case GL_LUMINANCE:
-          case GL_LUMINANCE_ALPHA:
-          case GL_RGB:
-          case GL_RGBA:
-          case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // Compressed textures are not supported here, but if they are unsupported altogether,
-          case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: // a different error is generated than otherwise. That is handled below.
-            break;
-          default:
-            return error(GL_INVALID_VALUE);
-        }
-
         if (border != 0)
         {
             return error(GL_INVALID_VALUE);
@@ -1029,20 +1000,38 @@
 
         if (context)
         {
-            if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || 
-                internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+            switch (target)
             {
-                if (context->supportsCompressedTextures())
+              case GL_TEXTURE_2D:
+                if (width > (context->getMaximumTextureDimension() >> level) ||
+                    height > (context->getMaximumTextureDimension() >> level))
                 {
-                    return error(GL_INVALID_OPERATION);
+                    return error(GL_INVALID_VALUE);
                 }
-                else
+                break;
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+                if (width != height)
                 {
-                    return error(GL_INVALID_ENUM);
+                    return error(GL_INVALID_VALUE);
                 }
+
+                if (width > (context->getMaximumCubeTextureDimension() >> level) ||
+                    height > (context->getMaximumCubeTextureDimension() >> level))
+                {
+                    return error(GL_INVALID_VALUE);
+                }
+                break;
+              default:
+                return error(GL_INVALID_ENUM);
             }
 
             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+
             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
             {
                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
@@ -1054,6 +1043,59 @@
             }
 
             gl::Colorbuffer *source = framebuffer->getColorbuffer();
+            GLenum colorbufferFormat = source->getFormat();
+
+            // [OpenGL ES 2.0.24] table 3.9
+            switch (internalformat)
+            {
+              case GL_ALPHA:
+                if (colorbufferFormat != GL_ALPHA &&
+                    colorbufferFormat != GL_RGBA &&
+                    colorbufferFormat != GL_RGBA4 &&
+                    colorbufferFormat != GL_RGB5_A1 &&
+                    colorbufferFormat != GL_RGBA8_OES)
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+                break;
+              case GL_LUMINANCE:
+              case GL_RGB:
+                if (colorbufferFormat != GL_RGB &&
+                    colorbufferFormat != GL_RGB565 &&
+                    colorbufferFormat != GL_RGB8_OES &&
+                    colorbufferFormat != GL_RGBA &&
+                    colorbufferFormat != GL_RGBA4 &&
+                    colorbufferFormat != GL_RGB5_A1 &&
+                    colorbufferFormat != GL_RGBA8_OES)
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+                break;
+              case GL_LUMINANCE_ALPHA:
+              case GL_RGBA:
+                if (colorbufferFormat != GL_RGBA &&
+                    colorbufferFormat != GL_RGBA4 &&
+                    colorbufferFormat != GL_RGB5_A1 &&
+                    colorbufferFormat != GL_RGBA8_OES)
+                 {
+                     return error(GL_INVALID_OPERATION);
+                 }
+                 break;
+              case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+              case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+                if (context->supportsCompressedTextures())
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+                else
+                {
+                    return error(GL_INVALID_ENUM);
+                }
+                break;
+              default:
+                return error(GL_INVALID_ENUM);
+            }
+
             if (target == GL_TEXTURE_2D)
             {
                 gl::Texture2D *texture = context->getTexture2D();
@@ -1062,11 +1104,6 @@
                 {
                     return error(GL_INVALID_OPERATION);
                 }
-                
-                if (texture->isCompressed())
-                {
-                    return error(GL_INVALID_OPERATION);
-                }
 
                 texture->copyImage(level, internalformat, x, y, width, height, source);
             }
@@ -1079,17 +1116,9 @@
                     return error(GL_INVALID_OPERATION);
                 }
 
-                if (texture->isCompressed())
-                {
-                    return error(GL_INVALID_OPERATION);
-                }
-
                 texture->copyImage(target, level, internalformat, x, y, width, height, source);
             }
-            else
-            {
-                UNREACHABLE();
-            }
+            else UNREACHABLE();
         }
     }
     catch(std::bad_alloc&)
@@ -1111,7 +1140,7 @@
             return error(GL_INVALID_ENUM);
         }
 
-        if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+        if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
         {
             return error(GL_INVALID_VALUE);
         }
@@ -1130,7 +1159,13 @@
 
         if (context)
         {
+            if (level > context->getMaximumTextureLevel())
+            {
+                return error(GL_INVALID_VALUE);
+            }
+
             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+
             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
             {
                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
@@ -1142,42 +1177,70 @@
             }
 
             gl::Colorbuffer *source = framebuffer->getColorbuffer();
+            GLenum colorbufferFormat = source->getFormat();
+            gl::Texture *texture = NULL;
+
             if (target == GL_TEXTURE_2D)
             {
-                gl::Texture2D *texture = context->getTexture2D();
-
-                if (!texture)
-                {
-                    return error(GL_INVALID_OPERATION);
-                }
-
-                if (texture->isCompressed())
-                {
-                    return error(GL_INVALID_OPERATION);
-                }
-
-                texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
+                texture = context->getTexture2D();
             }
             else if (gl::IsCubemapTextureTarget(target))
             {
-                gl::TextureCubeMap *texture = context->getTextureCubeMap();
-
-                if (!texture)
-                {
-                    return error(GL_INVALID_OPERATION);
-                }
-
-                if (texture->isCompressed())
-                {
-                    return error(GL_INVALID_OPERATION);
-                }
-
-                texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
+                texture = context->getTextureCubeMap();
             }
-            else
+            else UNREACHABLE();
+
+            if (!texture)
             {
-                UNREACHABLE();
+                return error(GL_INVALID_OPERATION);
             }
+
+            GLenum textureFormat = texture->getFormat();
+
+            // [OpenGL ES 2.0.24] table 3.9
+            switch (textureFormat)
+            {
+              case GL_ALPHA:
+                if (colorbufferFormat != GL_ALPHA &&
+                    colorbufferFormat != GL_RGBA &&
+                    colorbufferFormat != GL_RGBA4 &&
+                    colorbufferFormat != GL_RGB5_A1 &&
+                    colorbufferFormat != GL_RGBA8_OES)
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+                break;
+              case GL_LUMINANCE:
+              case GL_RGB:
+                if (colorbufferFormat != GL_RGB &&
+                    colorbufferFormat != GL_RGB565 &&
+                    colorbufferFormat != GL_RGB8_OES &&
+                    colorbufferFormat != GL_RGBA &&
+                    colorbufferFormat != GL_RGBA4 &&
+                    colorbufferFormat != GL_RGB5_A1 &&
+                    colorbufferFormat != GL_RGBA8_OES)
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+                break;
+              case GL_LUMINANCE_ALPHA:
+              case GL_RGBA:
+                if (colorbufferFormat != GL_RGBA &&
+                    colorbufferFormat != GL_RGBA4 &&
+                    colorbufferFormat != GL_RGB5_A1 &&
+                    colorbufferFormat != GL_RGBA8_OES)
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+                break;
+              case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+              case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+                return error(GL_INVALID_OPERATION);
+              default:
+                return error(GL_INVALID_OPERATION);
+            }
+
+            texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
         }
     }
 
@@ -1293,6 +1356,33 @@
     }
 }
 
+void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+    TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
+
+    try
+    {
+        if (n < 0)
+        {
+            return error(GL_INVALID_VALUE);
+        }
+
+        gl::Context *context = gl::getContext();
+
+        if (context)
+        {
+            for (int i = 0; i < n; i++)
+            {
+                context->deleteFence(fences[i]);
+            }
+        }
+    }
+    catch(std::bad_alloc&)
+    {
+        return error(GL_OUT_OF_MEMORY);
+    }
+}
+
 void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
 {
     TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
@@ -1624,7 +1714,7 @@
 
         if (context)
         {
-            context->setVertexAttribEnabled(index, false);
+            context->setEnableVertexAttribArray(index, false);
         }
     }
     catch(std::bad_alloc&)
@@ -1669,20 +1759,25 @@
             return error(GL_INVALID_VALUE);
         }
 
-        switch (type)
-        {
-          case GL_UNSIGNED_BYTE:
-          case GL_UNSIGNED_SHORT:
-          case GL_UNSIGNED_INT:
-            break;
-          default:
-            return error(GL_INVALID_ENUM);
-        }
-
         gl::Context *context = gl::getContext();
 
         if (context)
         {
+            switch (type)
+            {
+              case GL_UNSIGNED_BYTE:
+              case GL_UNSIGNED_SHORT:
+                break;
+              case GL_UNSIGNED_INT:
+                if (!context->supports32bitIndices())
+                {
+                    return error(GL_INVALID_ENUM);    
+                }
+                break;
+              default:
+                return error(GL_INVALID_ENUM);
+            }
+        
             context->drawElements(mode, count, type, indices);
         }
     }
@@ -1739,7 +1834,33 @@
 
         if (context)
         {
-            context->setVertexAttribEnabled(index, true);
+            context->setEnableVertexAttribArray(index, true);
+        }
+    }
+    catch(std::bad_alloc&)
+    {
+        return error(GL_OUT_OF_MEMORY);
+    }
+}
+
+void __stdcall glFinishFenceNV(GLuint fence)
+{
+    TRACE("(GLuint fence = %d)", fence);
+
+    try
+    {
+        gl::Context *context = gl::getContext();
+
+        if (context)
+        {
+            gl::Fence* fenceObject = context->getFence(fence);
+
+            if (fenceObject == NULL)
+            {
+                return error(GL_INVALID_OPERATION);
+            }
+
+            fenceObject->finishFence();
         }
     }
     catch(std::bad_alloc&)
@@ -2046,6 +2167,33 @@
     }
 }
 
+void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
+{
+    TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
+
+    try
+    {
+        if (n < 0)
+        {
+            return error(GL_INVALID_VALUE);
+        }
+
+        gl::Context *context = gl::getContext();
+
+        if (context)
+        {
+            for (int i = 0; i < n; i++)
+            {
+                fences[i] = context->createFence();
+            }
+        }
+    }
+    catch(std::bad_alloc&)
+    {
+        return error(GL_OUT_OF_MEMORY);
+    }
+}
+
 void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
 {
     TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
@@ -2421,6 +2569,33 @@
     return GL_NO_ERROR;
 }
 
+void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+    TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
+
+    try
+    {
+    
+        gl::Context *context = gl::getContext();
+
+        if (context)
+        {
+            gl::Fence *fenceObject = context->getFence(fence);
+
+            if (fenceObject == NULL)
+            {
+                return error(GL_INVALID_OPERATION);
+            }
+
+            fenceObject->getFenceiv(pname, params);
+        }
+    }
+    catch(std::bad_alloc&)
+    {
+        return error(GL_OUT_OF_MEMORY);
+    }
+}
+
 void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
 {
     TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
@@ -3287,12 +3462,12 @@
                 return error(GL_INVALID_VALUE);
             }
 
-            const gl::AttributeState &attribState = context->getVertexAttribState(index);
+            const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
 
             switch (pname)
             {
               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
-                *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
+                *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
                 *params = (GLfloat)attribState.mSize;
@@ -3340,12 +3515,12 @@
                 return error(GL_INVALID_VALUE);
             }
 
-            const gl::AttributeState &attribState = context->getVertexAttribState(index);
+            const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
 
             switch (pname)
             {
               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
-                *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
+                *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
                 break;
               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
                 *params = attribState.mSize;
@@ -3414,28 +3589,27 @@
 
     try
     {
-        switch (target)
+        switch (mode)
         {
-          case GL_GENERATE_MIPMAP_HINT:
-            switch (mode)
-            {
-              case GL_FASTEST:
-              case GL_NICEST:
-              case GL_DONT_CARE:
-                break;
-              default:
-                return error(GL_INVALID_ENUM); 
-            }
+          case GL_FASTEST:
+          case GL_NICEST:
+          case GL_DONT_CARE:
             break;
           default:
-              return error(GL_INVALID_ENUM);
+            return error(GL_INVALID_ENUM); 
         }
 
         gl::Context *context = gl::getContext();
-        if (context)
+        switch (target)
         {
-            if (target == GL_GENERATE_MIPMAP_HINT)
-                context->setGenerateMipmapHint(mode);
+          case GL_GENERATE_MIPMAP_HINT:
+            if (context) context->setGenerateMipmapHint(mode);
+            break;
+          case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+            if (context) context->setFragmentShaderDerivativeHint(mode);
+            break;
+          default:
+            return error(GL_INVALID_ENUM);
         }
     }
     catch(std::bad_alloc&)
@@ -3504,6 +3678,34 @@
     return false;
 }
 
+GLboolean __stdcall glIsFenceNV(GLuint fence)
+{
+    TRACE("(GLuint fence = %d)", fence);
+
+    try
+    {
+        gl::Context *context = gl::getContext();
+
+        if (context)
+        {
+            gl::Fence *fenceObject = context->getFence(fence);
+
+            if (fenceObject == NULL)
+            {
+                return GL_FALSE;
+            }
+
+            return fenceObject->isFence();
+        }
+    }
+    catch(std::bad_alloc&)
+    {
+        return error(GL_OUT_OF_MEMORY, GL_FALSE);
+    }
+
+    return GL_FALSE;
+}
+
 GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
 {
     TRACE("(GLuint framebuffer = %d)", framebuffer);
@@ -3841,22 +4043,12 @@
             return error(GL_INVALID_ENUM);
         }
 
-        switch (internalformat)
+        if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
         {
-          case GL_DEPTH_COMPONENT16:
-          case GL_RGBA4:
-          case GL_RGB5_A1:
-          case GL_RGB565:
-          case GL_STENCIL_INDEX8:
-          case GL_DEPTH24_STENCIL8_OES:
-          case GL_RGB8_OES:
-          case GL_RGBA8_OES:
-            break;
-          default:
             return error(GL_INVALID_ENUM);
         }
 
-        if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
+        if (width < 0 || height < 0 || samples < 0)
         {
             return error(GL_INVALID_VALUE);
         }
@@ -3865,7 +4057,9 @@
 
         if (context)
         {
-            if (samples > context->getMaxSupportedSamples())
+            if (width > context->getMaximumRenderbufferDimension() || 
+                height > context->getMaximumRenderbufferDimension() ||
+                samples > context->getMaxSupportedSamples())
             {
                 return error(GL_INVALID_VALUE);
             }
@@ -3929,6 +4123,37 @@
     }
 }
 
+void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
+{
+    TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
+
+    try
+    {
+        if (condition != GL_ALL_COMPLETED_NV)
+        {
+            return error(GL_INVALID_ENUM);
+        }
+
+        gl::Context *context = gl::getContext();
+
+        if (context)
+        {
+            gl::Fence *fenceObject = context->getFence(fence);
+
+            if (fenceObject == NULL)
+            {
+                return error(GL_INVALID_OPERATION);
+            }
+
+            fenceObject->setFence(condition);    
+        }
+    }
+    catch(std::bad_alloc&)
+    {
+        return error(GL_OUT_OF_MEMORY);
+    }
+}
+
 void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
 {
     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
@@ -4196,6 +4421,34 @@
     }
 }
 
+GLboolean __stdcall glTestFenceNV(GLuint fence)
+{
+    TRACE("(GLuint fence = %d)", fence);
+
+    try
+    {
+        gl::Context *context = gl::getContext();
+
+        if (context)
+        {
+            gl::Fence *fenceObject = context->getFence(fence);
+
+            if (fenceObject == NULL)
+            {
+                return error(GL_INVALID_OPERATION, GL_TRUE);
+            }
+
+            return fenceObject->testFence();
+        }
+    }
+    catch(std::bad_alloc&)
+    {
+        error(GL_OUT_OF_MEMORY);
+    }
+    
+    return GL_TRUE;
+}
+
 void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                             GLint border, GLenum format, GLenum type, const GLvoid* pixels)
 {
@@ -4215,34 +4468,6 @@
             return error(GL_INVALID_VALUE);
         }
 
-        switch (target)
-        {
-          case GL_TEXTURE_2D:
-            if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
-            {
-                return error(GL_INVALID_VALUE);
-            }
-            break;
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-            if (width != height)
-            {
-                return error(GL_INVALID_VALUE);
-            }
-
-            if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
-            {
-                return error(GL_INVALID_VALUE);
-            }
-            break;
-          default:
-            return error(GL_INVALID_ENUM);
-        }
-
         if (internalformat != format)
         {
             return error(GL_INVALID_OPERATION);
@@ -4256,6 +4481,8 @@
             switch (type)
             {
               case GL_UNSIGNED_BYTE:
+              case GL_FLOAT:
+              case GL_HALF_FLOAT_OES:
                 break;
               default:
                 return error(GL_INVALID_ENUM);
@@ -4266,6 +4493,8 @@
             {
               case GL_UNSIGNED_BYTE:
               case GL_UNSIGNED_SHORT_5_6_5:
+              case GL_FLOAT:
+              case GL_HALF_FLOAT_OES:
                 break;
               default:
                 return error(GL_INVALID_ENUM);
@@ -4277,6 +4506,8 @@
               case GL_UNSIGNED_BYTE:
               case GL_UNSIGNED_SHORT_4_4_4_4:
               case GL_UNSIGNED_SHORT_5_5_5_1:
+              case GL_FLOAT:
+              case GL_HALF_FLOAT_OES:
                 break;
               default:
                 return error(GL_INVALID_ENUM);
@@ -4307,6 +4538,36 @@
 
         if (context)
         {
+            switch (target)
+            {
+              case GL_TEXTURE_2D:
+                if (width > (context->getMaximumTextureDimension() >> level) ||
+                    height > (context->getMaximumTextureDimension() >> level))
+                {
+                    return error(GL_INVALID_VALUE);
+                }
+                break;
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+              case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+              case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+                if (width != height)
+                {
+                    return error(GL_INVALID_VALUE);
+                }
+
+                if (width > (context->getMaximumCubeTextureDimension() >> level) ||
+                    height > (context->getMaximumCubeTextureDimension() >> level))
+                {
+                    return error(GL_INVALID_VALUE);
+                }
+                break;
+              default:
+                return error(GL_INVALID_ENUM);
+            }
+
             if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
                 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
             {
@@ -4320,6 +4581,21 @@
                 }
             }
 
+            if (type == GL_FLOAT)
+            {
+                if (!context->supportsFloatTextures())
+                {
+                    return error(GL_INVALID_ENUM);
+                }
+            }
+            else if (type == GL_HALF_FLOAT_OES)
+            {
+                if (!context->supportsHalfFloatTextures())
+                {
+                    return error(GL_INVALID_ENUM);
+                }
+            }
+
             if (target == GL_TEXTURE_2D)
             {
                 gl::Texture2D *texture = context->getTexture2D();
@@ -4462,7 +4738,7 @@
             return error(GL_INVALID_ENUM);
         }
 
-        if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+        if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
         {
             return error(GL_INVALID_VALUE);
         }
@@ -4486,6 +4762,26 @@
 
         if (context)
         {
+            if (level > context->getMaximumTextureLevel())
+            {
+                return error(GL_INVALID_VALUE);
+            }
+
+            if (format == GL_FLOAT)
+            {
+                if (!context->supportsFloatTextures())
+                {
+                    return error(GL_INVALID_ENUM);
+                }
+            }
+            else if (format == GL_HALF_FLOAT_OES)
+            {
+                if (!context->supportsHalfFloatTextures())
+                {
+                    return error(GL_INVALID_ENUM);
+                }
+            }
+
             if (target == GL_TEXTURE_2D)
             {
                 gl::Texture2D *texture = context->getTexture2D();
@@ -4500,6 +4796,11 @@
                     return error(GL_INVALID_OPERATION);
                 }
 
+                if (format != texture->getFormat())
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+
                 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
             }
             else if (gl::IsCubemapTextureTarget(target))
@@ -4516,6 +4817,11 @@
                     return error(GL_INVALID_OPERATION);
                 }
 
+                if (format != texture->getFormat())
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+
                 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
             }
             else
@@ -5435,6 +5741,14 @@
     {
         {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
         {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
+        {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
+        {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
+        {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
+        {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
+        {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
+        {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
+        {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
+        {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
     };
 
     for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def
index a043ed8..b2dc23c 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def
@@ -147,7 +147,14 @@
     glTexImage3DOES                 @143
     glBlitFramebufferANGLE          @149
     glRenderbufferStorageMultisampleANGLE @150
-    
+    glDeleteFencesNV                @151
+    glFinishFenceNV                 @152
+    glGenFencesNV                   @153
+    glGetFenceivNV                  @154
+    glIsFenceNV                     @155
+    glSetFenceNV                    @156
+    glTestFenceNV                   @157
+
     ; EGL dependencies
     glCreateContext                 @144 NONAME
     glDestroyContext                @145 NONAME
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj
index 1f43e7a..0d95080 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj
@@ -201,6 +201,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Fence.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\Framebuffer.cpp"
 				>
 			</File>
@@ -244,14 +248,6 @@
 				Name="Geometry"
 				>
 				<File
-					RelativePath=".\geometry\backend.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\geometry\dx9.cpp"
-					>
-				</File>
-				<File
 					RelativePath=".\geometry\IndexDataManager.cpp"
 					>
 				</File>
@@ -279,6 +275,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Fence.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Framebuffer.h"
 				>
 			</File>
@@ -334,14 +334,6 @@
 				Name="Geometry"
 				>
 				<File
-					RelativePath=".\geometry\backend.h"
-					>
-				</File>
-				<File
-					RelativePath=".\geometry\dx9.h"
-					>
-				</File>
-				<File
 					RelativePath=".\geometry\IndexDataManager.h"
 					>
 				</File>
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp
index 7fc2bc4..a3f5243 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp
@@ -25,6 +25,8 @@
       case GL_BOOL:
       case GL_FLOAT:
       case GL_INT:
+      case GL_SAMPLER_2D:
+      case GL_SAMPLER_CUBE:
           return 1;
       case GL_BOOL_VEC2:
       case GL_FLOAT_VEC2:
@@ -68,6 +70,8 @@
       case GL_FLOAT_MAT4:
           return GL_FLOAT;
       case GL_INT:
+      case GL_SAMPLER_2D:
+      case GL_SAMPLER_CUBE:
       case GL_INT_VEC2:
       case GL_INT_VEC3:
       case GL_INT_VEC4:
@@ -247,6 +251,28 @@
       case GL_UNSIGNED_SHORT_5_5_5_1:
       case GL_UNSIGNED_SHORT_5_6_5:
         return sizeof(unsigned short);
+      case GL_FLOAT:
+        switch (format)
+        {
+          case GL_ALPHA:           return sizeof(float);
+          case GL_LUMINANCE:       return sizeof(float);
+          case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
+          case GL_RGB:             return sizeof(float) * 3;
+          case GL_RGBA:            return sizeof(float) * 4;
+          default: UNREACHABLE();
+        }
+        break;
+      case GL_HALF_FLOAT_OES:
+        switch (format)
+        {
+          case GL_ALPHA:           return sizeof(unsigned short);
+          case GL_LUMINANCE:       return sizeof(unsigned short);
+          case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
+          case GL_RGB:             return sizeof(unsigned short) * 3;
+          case GL_RGBA:            return sizeof(unsigned short) * 4;
+          default: UNREACHABLE();
+        }
+        break;
       default: UNREACHABLE();
     }
 
@@ -283,6 +309,21 @@
             return false;
         }
 
+      case GL_FLOAT:
+      case GL_HALF_FLOAT_OES:
+        switch (format)
+        {
+          case GL_RGBA:
+          case GL_RGB:
+          case GL_ALPHA:
+          case GL_LUMINANCE:
+          case GL_LUMINANCE_ALPHA:
+            return true;
+
+          default:
+            return false;
+        }
+
       case GL_UNSIGNED_SHORT_4_4_4_4:
       case GL_UNSIGNED_SHORT_5_5_5_1:
         return (format == GL_RGBA);
@@ -295,6 +336,69 @@
     }
 }
 
+bool IsColorRenderable(GLenum internalformat)
+{
+    switch (internalformat)
+    {
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGB565:
+      case GL_RGB8_OES:
+      case GL_RGBA8_OES:
+        return true;
+      case GL_DEPTH_COMPONENT16:
+      case GL_STENCIL_INDEX8:
+      case GL_DEPTH24_STENCIL8_OES:
+        return false;
+      default:
+        UNIMPLEMENTED();
+    }
+
+    return false;
+}
+
+bool IsDepthRenderable(GLenum internalformat)
+{
+    switch (internalformat)
+    {
+      case GL_DEPTH_COMPONENT16:
+      case GL_DEPTH24_STENCIL8_OES:
+        return true;
+      case GL_STENCIL_INDEX8:
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGB565:
+      case GL_RGB8_OES:
+      case GL_RGBA8_OES:
+        return false;
+      default:
+        UNIMPLEMENTED();
+    }
+
+    return false;
+}
+
+bool IsStencilRenderable(GLenum internalformat)
+{
+    switch (internalformat)
+    {
+      case GL_STENCIL_INDEX8:
+      case GL_DEPTH24_STENCIL8_OES:
+        return true;
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGB565:
+      case GL_RGB8_OES:
+      case GL_RGBA8_OES:
+      case GL_DEPTH_COMPONENT16:
+        return false;
+      default:
+        UNIMPLEMENTED();
+    }
+
+    return false;
+}
+
 }
 
 namespace es2dx
@@ -508,6 +612,10 @@
 {
     switch (colorFormat)
     {
+      case D3DFMT_A16B16G16R16F:
+        return 16;
+      case D3DFMT_A32B32G32R32F:
+        return 32;
       case D3DFMT_A2R10G10B10:
         return 2;
       case D3DFMT_A8R8G8B8:
@@ -515,7 +623,6 @@
       case D3DFMT_A1R5G5B5:
         return 1;
       case D3DFMT_X8R8G8B8:
-      case D3DFMT_X1R5G5B5:
       case D3DFMT_R5G6B5:
         return 0;
       default: UNREACHABLE();
@@ -527,6 +634,10 @@
 {
     switch (colorFormat)
     {
+      case D3DFMT_A16B16G16R16F:
+        return 16;
+      case D3DFMT_A32B32G32R32F:
+        return 32;
       case D3DFMT_A2R10G10B10:
         return 10;
       case D3DFMT_A8R8G8B8:
@@ -534,7 +645,6 @@
         return 8;
       case D3DFMT_A1R5G5B5:
       case D3DFMT_R5G6B5:
-      case D3DFMT_X1R5G5B5:
         return 5;
       default: UNREACHABLE();
     }
@@ -545,13 +655,16 @@
 {
     switch (colorFormat)
     {
+      case D3DFMT_A16B16G16R16F:
+        return 16;
+      case D3DFMT_A32B32G32R32F:
+        return 32;
       case D3DFMT_A2R10G10B10:
         return 10;
       case D3DFMT_A8R8G8B8:
       case D3DFMT_X8R8G8B8:
         return 8;
       case D3DFMT_A1R5G5B5:
-      case D3DFMT_X1R5G5B5:
         return 5;
       case D3DFMT_R5G6B5:
         return 6;
@@ -564,6 +677,10 @@
 {
     switch (colorFormat)
     {
+      case D3DFMT_A16B16G16R16F:
+        return 16;
+      case D3DFMT_A32B32G32R32F:
+        return 32;
       case D3DFMT_A2R10G10B10:
         return 10;
       case D3DFMT_A8R8G8B8:
@@ -571,7 +688,6 @@
         return 8;
       case D3DFMT_A1R5G5B5:
       case D3DFMT_R5G6B5:
-      case D3DFMT_X1R5G5B5:
         return 5;
       default: UNREACHABLE();
     }
@@ -591,46 +707,46 @@
       case D3DFMT_D16:           return 16;
       case D3DFMT_D32F_LOCKABLE: return 32;
       case D3DFMT_D24FS8:        return 24;
-//      case D3DFMT_D32_LOCKABLE:  return 32;   // D3D9Ex only
-//      case D3DFMT_S8_LOCKABLE:   return 0;    // D3D9Ex only
+    //case D3DFMT_D32_LOCKABLE:  return 32;   // D3D9Ex only
+    //case D3DFMT_S8_LOCKABLE:   return 0;    // D3D9Ex only
       default:
         UNREACHABLE();
     }
     return 0;
 }
 
-bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
+bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
                           D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
 {
     switch (primitiveType)
     {
       case GL_POINTS:
         *d3dPrimitiveType = D3DPT_POINTLIST;
-        *d3dPrimitiveCount = primitiveCount;
+        *d3dPrimitiveCount = elementCount;
         break;
       case GL_LINES:
         *d3dPrimitiveType = D3DPT_LINELIST;
-        *d3dPrimitiveCount = primitiveCount / 2;
+        *d3dPrimitiveCount = elementCount / 2;
         break;
       case GL_LINE_LOOP:
         *d3dPrimitiveType = D3DPT_LINESTRIP;
-        *d3dPrimitiveCount = primitiveCount;
+        *d3dPrimitiveCount = elementCount - 1;   // D3D doesn't support line loops, so we draw the last line separately
         break;
       case GL_LINE_STRIP:
         *d3dPrimitiveType = D3DPT_LINESTRIP;
-        *d3dPrimitiveCount = primitiveCount - 1;
+        *d3dPrimitiveCount = elementCount - 1;
         break;
       case GL_TRIANGLES:
         *d3dPrimitiveType = D3DPT_TRIANGLELIST;
-        *d3dPrimitiveCount = primitiveCount / 3;
+        *d3dPrimitiveCount = elementCount / 3;
         break;
       case GL_TRIANGLE_STRIP:
         *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
-        *d3dPrimitiveCount = primitiveCount - 2;
+        *d3dPrimitiveCount = elementCount - 2;
         break;
       case GL_TRIANGLE_FAN:
         *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
-        *d3dPrimitiveCount = primitiveCount - 2;
+        *d3dPrimitiveCount = elementCount - 2;
         break;
       default:
         return false;
@@ -672,3 +788,40 @@
 }
 
 }
+
+namespace dx2es
+{
+
+GLenum ConvertBackBufferFormat(D3DFORMAT format)
+{
+    switch (format)
+    {
+      case D3DFMT_A4R4G4B4: return GL_RGBA4;
+      case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
+      case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
+      case D3DFMT_R5G6B5:   return GL_RGB565;
+      case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_RGBA4;
+}
+
+GLenum ConvertDepthStencilFormat(D3DFORMAT format)
+{
+    switch (format)
+    {
+      case D3DFMT_D16:
+      case D3DFMT_D24X8:
+        return GL_DEPTH_COMPONENT16;
+      case D3DFMT_D24S8:
+        return GL_DEPTH24_STENCIL8_OES;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_DEPTH24_STENCIL8_OES;
+}
+
+}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h
index b6c8ce5..85e8f26 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h
@@ -36,6 +36,10 @@
 bool IsTextureTarget(GLenum target);
 bool CheckTextureFormatType(GLenum format, GLenum type);
 
+bool IsColorRenderable(GLenum internalformat);
+bool IsDepthRenderable(GLenum internalformat);
+bool IsStencilRenderable(GLenum internalformat);
+
 }
 
 namespace es2dx
@@ -57,7 +61,7 @@
 unsigned int GetBlueSize(D3DFORMAT colorFormat);
 unsigned int GetDepthSize(D3DFORMAT depthFormat);
 unsigned int GetStencilSize(D3DFORMAT stencilFormat);
-bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
+bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
                           D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
 D3DFORMAT ConvertRenderbufferFormat(GLenum format);
 D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
@@ -65,4 +69,12 @@
 
 }
 
+namespace dx2es
+{
+
+GLenum ConvertBackBufferFormat(D3DFORMAT format);
+GLenum ConvertDepthStencilFormat(D3DFORMAT format);
+
+}
+
 #endif  // LIBGLESV2_UTILITIES_H
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 0d12287..47b95f5 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2011-01-18  Ben Vanik  <ben.vanik@gmail.com>
+
+        Reviewed by Kenneth Russell.
+
+        Updating ANGLE in WebKit to r533.
+        https://bugs.webkit.org/show_bug.cgi?id=47194
+
+        * platform/graphics/ANGLEWebKitBridge.cpp:
+        (WebCore::ANGLEWebKitBridge::ANGLEWebKitBridge):
+        (WebCore::ANGLEWebKitBridge::~ANGLEWebKitBridge):
+        (WebCore::ANGLEWebKitBridge::validateShaderSource):
+        Update to new ANGLE API for shader validation.
+        * platform/graphics/ANGLEWebKitBridge.h:
+        (WebCore::ANGLEWebKitBridge::setResources): 
+        Renaming types to new names.
+        * platform/graphics/mac/GraphicsContext3DMac.mm:
+        (WebCore::GraphicsContext3D::GraphicsContext3D):
+        Initialize ANGLEResources with ANGLE init call to prevent uninitialized variables.
+
 2011-01-18  MORITA Hajime  <morrita@google.com>
 
         Reviewed by Simon Fraser.
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
index 64f19c4..d1fc69c 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
@@ -28,29 +28,43 @@
 #if ENABLE(3D_CANVAS)
 
 #include "ANGLEWebKitBridge.h"
+#include <wtf/OwnArrayPtr.h>
 
 namespace WebCore {
 
 
 ANGLEWebKitBridge::ANGLEWebKitBridge() :
-    builtCompilers(false)
+    builtCompilers(false),
+    m_fragmentCompiler(0),
+    m_vertexCompiler(0)
 {
     ShInitialize();
 }
 
 ANGLEWebKitBridge::~ANGLEWebKitBridge()
 {
-    if (builtCompilers) {
+    if (m_fragmentCompiler)
         ShDestruct(m_fragmentCompiler);
+    m_fragmentCompiler = 0;
+    if (m_vertexCompiler)
         ShDestruct(m_vertexCompiler);
-    }
+    m_vertexCompiler = 0;
 }
 
 bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog)
 {
     if (!builtCompilers) {
-        m_fragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecWebGL, &m_resources);
-        m_vertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecWebGL, &m_resources);
+        m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, &m_resources);
+        m_vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_WEBGL_SPEC, &m_resources);
+        if (!m_fragmentCompiler || !m_vertexCompiler) {
+            if (m_fragmentCompiler)
+                ShDestruct(m_fragmentCompiler);
+            m_fragmentCompiler = 0;
+            if (m_vertexCompiler)
+                ShDestruct(m_vertexCompiler);
+            m_vertexCompiler = 0;
+            return false;
+        }
 
         builtCompilers = true;
     }
@@ -64,12 +78,31 @@
 
     const char* const shaderSourceStrings[] = { shaderSource };
 
-    bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, EShOptNone, EDebugOpIntermediate);
+    bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, SH_OBJECT_CODE);
+    if (!validateSuccess) {
+        int logSize = 0;
+        ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &logSize);
+        if (logSize > 1) {
+            OwnArrayPtr<char> logBuffer(new char[logSize]);
+            if (logBuffer) {
+                ShGetInfoLog(compiler, logBuffer.get());
+                shaderValidationLog = logBuffer.get();
+            }
+        }
+        return false;
+    }
 
-    translatedShaderSource = ShGetObjectCode(compiler);
-    shaderValidationLog = ShGetInfoLog(compiler);
+    int translationLength = 0;
+    ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &translationLength);
+    if (translationLength > 1) {
+        OwnArrayPtr<char> translationBuffer(new char[translationLength]);
+        if (!translationBuffer)
+            return false;
+        ShGetObjectCode(compiler, translationBuffer.get());
+        translatedShaderSource = translationBuffer.get();
+    }
 
-    return validateSuccess;
+    return true;
 }
 
 }
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
index d01de8f..b68748b 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
@@ -34,8 +34,8 @@
 namespace WebCore {
 
 enum ANGLEShaderType {
-    SHADER_TYPE_VERTEX = EShLangVertex,
-    SHADER_TYPE_FRAGMENT = EShLangFragment
+    SHADER_TYPE_VERTEX = SH_VERTEX_SHADER,
+    SHADER_TYPE_FRAGMENT = SH_FRAGMENT_SHADER,
 };
 
 class ANGLEWebKitBridge {
@@ -44,18 +44,18 @@
     ANGLEWebKitBridge();
     ~ANGLEWebKitBridge();
     
-    void setResources(TBuiltInResource resources) { m_resources = resources; }
+    void setResources(ShBuiltInResources resources) { m_resources = resources; }
     
     bool validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog);
 
 private:
 
+    bool builtCompilers;
+    
     ShHandle m_fragmentCompiler;
     ShHandle m_vertexCompiler;
 
-    bool builtCompilers;
-
-    TBuiltInResource m_resources;
+    ShBuiltInResources m_resources;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index 321d0ef..21eb59d 100644
--- a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -188,21 +188,15 @@
     
     // ANGLE initialization.
 
-    TBuiltInResource ANGLEResources;
+    ShBuiltInResources ANGLEResources;
+    ShInitBuiltInResources(&ANGLEResources);
 
-    ANGLEResources.MaxVertexAttribs = 0;
     getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs);
-    ANGLEResources.MaxVertexUniformVectors = 0;
     getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors);
-    ANGLEResources.MaxVaryingVectors = 0;
     getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors);
-    ANGLEResources.MaxVertexTextureImageUnits = 0;
     getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits);
-    ANGLEResources.MaxCombinedTextureImageUnits = 0;
     getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits);
-    ANGLEResources.MaxTextureImageUnits = 0;
     getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits);
-    ANGLEResources.MaxFragmentUniformVectors = 0;
     getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors);
 
     // Always set to 1 for OpenGL ES.