text:
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax

Namespace Microsoft.CodeAnalysis.VisualBasic

    ''' <summary>
    ''' The <see cref="LocalBinderBuilder"/> is used to build up the map of all <see cref="Binder"/>s within a method body, and the associated
    ''' <see cref="VisualBasicSyntaxNode"/>. To do so it traverses all the statements, handling blocks and other
    ''' statements that create scopes. For efficiency reasons, it does not traverse into
    ''' expressions. This means that blocks within lambdas and queries are not created.
    ''' Blocks within lambdas are bound by their own <see cref="LocalBinderBuilder"/> when they are
    ''' analyzed.
    '''
    ''' For reasons of lifetime management, this type is distinct from the <see
    ''' cref="BinderFactory"/>
    ''' which also creates a map from <see cref="VisualBasicSyntaxNode"/> to <see cref="Binder"/>. That type owns it's binders
    ''' and that type's lifetime is that of the compilation. Therefore we do not store
    ''' binders local to method bodies in that type's cache.
    ''' </summary>
    Friend Class LocalBinderBuilder
        Inherits VisualBasicSyntaxVisitor

        Private _nodeMap As ImmutableDictionary(Of VisualBasicSyntaxNode, BlockBaseBinder)
        Private _listMap As ImmutableDictionary(Of SyntaxList(Of StatementSyntax), BlockBaseBinder)
        Private _enclosingMethod As MethodSymbol
        Private containingBinder As Binder

        Public Sub New(enclosingMethod As MethodSymbol)
            _enclosingMethod = enclosingMethod
            _nodeMap = ImmutableDictionary.Create(Of VisualBasicSyntaxNode, BlockBaseBinder)()
            _listMap = ImmutableDictionary.Create(Of SyntaxList(Of StatementSyntax), BlockBaseBinder)()
        End Sub

        Public Sub New(enclosingMethod As MethodSymbol, nodeMap As ImmutableDictionary(Of VisualBasicSyntaxNode, BlockBaseBinder), listMap As ImmutableDictionary(Of SyntaxList(Of StatementSyntax), BlockBaseBinder))
            _enclosingMethod = enclosingMethod
            _nodeMap = nodeMap
            _listMap = listMap
        End Sub

        Public Sub MakeBinder(node As VisualBasicSyntaxNode, containingBinder As Binder)
            Dim oldContainingBinder As Binder = Me.containingBinder
            Me.containingBinder = containingBinder
            MyBase.Visit(node)
            Me.containingBinder = oldContainingBinder
        End Sub

        Public ReadOnly Property NodeToBinderMap As ImmutableDictionary(Of VisualBasicSyntaxNode, BlockBaseBinder)
            Get
                Return _nodeMap
            End Get
        End Property

        Public ReadOnly Property StmtListToBinderMap As ImmutableDictionary(Of SyntaxList(Of StatementSyntax), BlockBaseBinder)
            Get
                Return _listMap
            End Get
        End Property

        ' Visit the statements in a statement list. Does not create a containing binder.
        Private Sub VisitStatementsInList(list As IEnumerable(Of StatementSyntax), currentBinder As BlockBaseBinder)
            For Each n In list
                MakeBinder(n, currentBinder)
            Next
        End Sub

        ' Create a binder using the given statement list.
        Private Sub CreateBinderFromStatementList(list As SyntaxList(Of StatementSyntax), outerBinder As Binder)
            Dim newBinder = New StatementListBinder(outerBinder, list)
            _listMap = _listMap.SetItem(list, newBinder)
            VisitStatementsInList(list, newBinder)
        End Sub

        ' Add a binder to the map.
        Private Sub RememberBinder(node As VisualBasicSyntaxNode, binder As Binder)
            _nodeMap = _nodeMap.SetItem(node, DirectCast(binder, BlockBaseBinder))
        End Sub

        ''' <summary>
        ''' Creates binders for top-level executable statements.
        ''' </summary>
        Public Overrides Sub VisitCompilationUnit(node As CompilationUnitSyntax)
            For Each member In node.Members
                ' Visit methods for non-executable statements are no-ops:
                MakeBinder(member, containingBinder)
            Next
        End Sub

        Public Overrides Sub VisitMethodBlock(node As MethodBlockSyntax)
            VisitMethodBlockBase(node)
        End Sub

        Public Overrides Sub VisitConstructorBlock(node As ConstructorBlockSyntax)
            VisitMethodBlockBase(node)
        End Sub

        Public Overrides Sub VisitOperatorBlock(node As OperatorBlockSyntax)
            VisitMethodBlockBase(node)
        End Sub

        Public Overrides Sub VisitAccessorBlock(node As AccessorBlockSyntax)
            VisitMethodBlockBase(node)
        End Sub

        Private Sub VisitMethodBlockBase(methodBlock As MethodBlockBaseSyntax)
            ' Get the right kind of exit kind for this method.
            Dim exitKind As SyntaxKind
            Select Case methodBlock.BlockStatement.Kind
                Case SyntaxKind.SubStatement, SyntaxKind.SubNewStatement
                    exitKind = SyntaxKind.ExitSubStatement

                Case SyntaxKind.FunctionStatement
                    exitKind = SyntaxKind.ExitFunctionStatement

                Case SyntaxKind.GetAccessorStatement, SyntaxKind.SetAccessorStatement
                    exitKind = SyntaxKind.ExitPropertyStatement

                Case SyntaxKind.AddHandlerAccessorStatement, SyntaxKind.RemoveHandlerAccessorStatement,
                     SyntaxKind.RaiseEventAccessorStatement

                    ' this is not an Exit kind (there is no such thing as "Exit AddHandler")
                    ' We just use this so that we get a return label.
                    exitKind = SyntaxKind.EventStatement

                Case SyntaxKind.OperatorStatement
                    ' Exit Operator does not exist
                    'exitKind = SyntaxKind.ExitOperatorStatement
                    exitKind = SyntaxKind.OperatorStatement

                Case Else
                    Throw ExceptionUtilities.UnexpectedValue(methodBlock.BlockStatement.Kind)
            End Select

            containingBinder = New ExitableStatementBinder(containingBinder,
                                                           continueKind:=SyntaxKind.None, exitKind:=exitKind)
            RememberBinder(methodBlock, containingBinder)

            CreateBinderFromStatementList(methodBlock.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitSingleLineLambdaExpression(node As SingleLineLambdaExpressionSyntax)
            If node Is _enclosingMethod.Syntax Then
                Dim exitKind As SyntaxKind

                Select Case node.Kind
                    Case SyntaxKind.SingleLineSubLambdaExpression
                        exitKind = SyntaxKind.ExitSubStatement
                    Case SyntaxKind.SingleLineFunctionLambdaExpression
                        exitKind = SyntaxKind.ExitFunctionStatement
                    Case Else
                        Throw ExceptionUtilities.UnexpectedValue(node.Kind)
                End Select

                containingBinder = New ExitableStatementBinder(containingBinder,
                                                               continueKind:=SyntaxKind.None, exitKind:=exitKind)
                RememberBinder(node, containingBinder)

                If node.Kind = SyntaxKind.SingleLineSubLambdaExpression Then
                    ' Even though single line sub lambdas only have a single statement.  Create a binder for
                    ' a statement list so that locals can be bound. Note, while locals are not allowed at the top
                    ' level it is useful in the semantic model to bind them.
                    CreateBinderFromStatementList(node.Statements, containingBinder)
                End If

                MakeBinder(node.Body, containingBinder)

                Return
            Else
                MyBase.VisitSingleLineLambdaExpression(node) : Return
            End If
        End Sub

        Public Overrides Sub VisitMultiLineLambdaExpression(node As MultiLineLambdaExpressionSyntax)
            If node Is _enclosingMethod.Syntax Then
                Dim exitKind As SyntaxKind

                Select Case node.Kind
                    Case SyntaxKind.MultiLineSubLambdaExpression
                        exitKind = SyntaxKind.ExitSubStatement
                    Case SyntaxKind.MultiLineFunctionLambdaExpression
                        exitKind = SyntaxKind.ExitFunctionStatement
                    Case Else
                        Throw ExceptionUtilities.UnexpectedValue(node.Kind)
                End Select

                containingBinder = New ExitableStatementBinder(containingBinder,
                                                               continueKind:=SyntaxKind.None, exitKind:=exitKind)
                RememberBinder(node, containingBinder)

                CreateBinderFromStatementList(node.Statements, containingBinder)

                Return
            Else
                MyBase.VisitMultiLineLambdaExpression(node) : Return
            End If
        End Sub

        Public Overrides Sub VisitWhileBlock(node As WhileBlockSyntax)
            containingBinder = New ExitableStatementBinder(containingBinder,
                                                           continueKind:=SyntaxKind.ContinueWhileStatement, exitKind:=SyntaxKind.ExitWhileStatement)
            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitUsingBlock(node As UsingBlockSyntax)
            containingBinder = New UsingBlockBinder(containingBinder, node)

            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitSyncLockBlock(node As SyncLockBlockSyntax)
            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitWithBlock(node As WithBlockSyntax)
            containingBinder = New WithBlockBinder(containingBinder, node)

            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitSingleLineIfStatement(node As SingleLineIfStatementSyntax)
            CreateBinderFromStatementList(node.Statements, containingBinder)
            MakeBinder(node.ElseClause, containingBinder)
        End Sub

        Public Overrides Sub VisitSingleLineElseClause(node As SingleLineElseClauseSyntax)
            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitMultiLineIfBlock(node As MultiLineIfBlockSyntax)
            CreateBinderFromStatementList(node.Statements, containingBinder)

            For Each elseifBlock In node.ElseIfBlocks
                MakeBinder(elseifBlock, containingBinder)
            Next

            MakeBinder(node.ElseBlock, containingBinder)
        End Sub

        Public Overrides Sub VisitElseBlock(node As ElseBlockSyntax)
            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitElseIfBlock(node As ElseIfBlockSyntax)
            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitTryBlock(node As TryBlockSyntax)
            containingBinder = New ExitableStatementBinder(containingBinder,
                                                           continueKind:=SyntaxKind.None, exitKind:=SyntaxKind.ExitTryStatement)
            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
            For Each catchBlock In node.CatchBlocks
                MakeBinder(catchBlock, containingBinder)
            Next
            MakeBinder(node.FinallyBlock, containingBinder)
        End Sub

        Public Overrides Sub VisitCatchBlock(node As CatchBlockSyntax)
            containingBinder = New CatchBlockBinder(containingBinder, node)

            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitFinallyBlock(node As FinallyBlockSyntax)
            containingBinder = New FinallyBlockBinder(containingBinder)

            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitSelectBlock(node As SelectBlockSyntax)
            containingBinder = New ExitableStatementBinder(containingBinder,
                                                           continueKind:=SyntaxKind.None, exitKind:=SyntaxKind.ExitSelectStatement)
            RememberBinder(node, containingBinder)

            For Each caseBlock In node.CaseBlocks
                MakeBinder(caseBlock, containingBinder)
            Next
        End Sub

        Public Overrides Sub VisitCaseBlock(node As CaseBlockSyntax)
            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitDoLoopBlock(node As DoLoopBlockSyntax)
            containingBinder = New ExitableStatementBinder(containingBinder,
                                                           continueKind:=SyntaxKind.ContinueDoStatement, exitKind:=SyntaxKind.ExitDoStatement)
            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitForBlock(node As ForBlockSyntax)
            containingBinder = New ForOrForEachBlockBinder(containingBinder, node)

            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

        Public Overrides Sub VisitForEachBlock(node As ForEachBlockSyntax)
            containingBinder = New ForOrForEachBlockBinder(containingBinder, node)

            RememberBinder(node, containingBinder)

            CreateBinderFromStatementList(node.Statements, containingBinder)
        End Sub

    End Class

End Namespace


text:
module VoluntaryScholarship
  class Ability
    def self.after_initialize
      Proc.new do |ability, user, options|
        ability.can :read, [
          Scholarship::Team, Scholarship::TeamMembership, Scholarship::Program, Scholarship::Iteration, Scholarship::IterationParticipation
        ]

        if user.present?
          ability.can(:restful_actions, Scholarship::Team) {|team| team.new_record? || user.is_leader_of_scholarship_team?(team) }

          ability.can(:restful_actions, Scholarship::TeamMembership) do |membership|
            membership.new_record? || membership.user_id == user.id || user.is_leader_of_scholarship_team?(membership.team)
          end

          ability.can([:with_state] + Scholarship::TeamMembership::EVENTS, Scholarship::TeamMembership) do |membership|
            user.is_leader_of_scholarship_team?(membership.team)
          end

          ability.can(:restful_actions, Scholarship::IterationParticipation) do |participation|
            participation.new_record? || participation.user_id == user.id || user.id == participation.iteration.program.organization.user_id
          end

          ability.can([:with_state] + Scholarship::IterationParticipation::EVENTS, Scholarship::IterationParticipation) do |participation|
            user.id == participation.iteration.program.organization.user_id
          end

          ability.can(:restful_actions, Scholarship::Program) {|program| program.organization.blank? || program.organization.user_id == user.id }
          ability.can(:restful_actions, Scholarship::Iteration) {|iteration| iteration.program.blank? || iteration.program.organization.user_id == user.id }
        end
      end
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

//----------------------------------------------------------------------------
//

//
// Stack unwinding implementation for x64.
//

//
//----------------------------------------------------------------------------

#include "pch.cpp"
#pragma hdrstop

//----------------------------------------------------------------------------
//
// Copied OS code.
//
// This must be kept in sync with the system unwinder.
// base\ntos\rtl\amd64\exdsptch.c
//
//----------------------------------------------------------------------------

//
// Lookup table providing the number of slots used by each unwind code.
//

UCHAR
DbsX64StackUnwinder::s_UnwindOpSlotTable[] =
{
    1,          // UWOP_PUSH_NONVOL
    2,          // UWOP_ALLOC_LARGE (or 3, special cased in lookup code)
    1,          // UWOP_ALLOC_SMALL
    1,          // UWOP_SET_FPREG
    2,          // UWOP_SAVE_NONVOL
    3,          // UWOP_SAVE_NONVOL_FAR
    2,          // UWOP_SAVE_XMM
    3,          // UWOP_SAVE_XMM_FAR
    2,          // UWOP_SAVE_XMM128
    3,          // UWOP_SAVE_XMM128_FAR
    1           // UWOP_PUSH_MACHFRAME
};

//
// ****** temp - defin elsewhere ******
//

#define SIZE64_PREFIX 0x48
#define ADD_IMM8_OP 0x83
#define ADD_IMM32_OP 0x81
#define JMP_IMM8_OP 0xeb
#define JMP_IMM32_OP 0xe9
#define JMP_IND_OP 0xff
#define LEA_OP 0x8d
#define REP_PREFIX 0xf3
#define POP_OP 0x58
#define RET_OP 0xc3
#define RET_OP_2 0xc2

#define IS_REX_PREFIX(x) (((x) & 0xf0) == 0x40)

HRESULT
DbsX64StackUnwinder::UnwindPrologue(
    __in ULONG64 ImageBase,
    __in ULONG64 ControlPc,
    __in ULONG64 FrameBase,
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __inout PAMD64_CONTEXT ContextRecord
    )

/*++

Routine Description:

    This function processes unwind codes and reverses the state change
    effects of a prologue. If the specified unwind information contains
    chained unwind information, then that prologue is unwound recursively.
    As the prologue is unwound state changes are recorded in the specified
    context structure and optionally in the specified context pointers
    structures.

Arguments:

    ImageBase - Supplies the base address of the image that contains the
        function being unwound.

    ControlPc - Supplies the address where control left the specified
        function.

    FrameBase - Supplies the base of the stack frame subject function stack
         frame.

    FunctionEntry - Supplies the address of the function table entry for the
        specified function.

    ContextRecord - Supplies the address of a context record.

--*/

{

    HRESULT Status = E_UNEXPECTED;
    ULONG64 FloatingAddress;
    PAMD64_M128 FloatingRegister;
    ULONG FrameOffset;
    ULONG Index;
    ULONG64 IntegerAddress;
    PULONG64 IntegerRegister;
    BOOLEAN MachineFrame;
    ULONG OpInfo;
    ULONG PrologOffset;
    ULONG64 ReturnAddress;
    ULONG64 StackAddress;
    ULONG64 UnwindInfoBuffer[32];
    PAMD64_UNWIND_INFO UnwindInfo;
    ULONG UnwindOp;

    //
    // Process the unwind codes.
    //

    FloatingRegister = &ContextRecord->Xmm0;
    IntegerRegister = &ContextRecord->Rax;
    Index = 0;
    MachineFrame = FALSE;
    PrologOffset = (ULONG)(ControlPc - (FunctionEntry->BeginAddress + ImageBase));

    m_Services->Status(1, "Prol: RIP %I64X, 0x%X bytes in function at %I64X\n",
                       ControlPc, PrologOffset,
                       FunctionEntry->BeginAddress + ImageBase);
    m_Services->Status(1, "Prol: Read unwind info at %I64X\n",
                       FunctionEntry->UnwindInfoAddress + ImageBase);

    if ((Status =
         GetUnwindInfo(ImageBase, FunctionEntry->UnwindInfoAddress,
                       false,
                       UnwindInfoBuffer, sizeof(UnwindInfoBuffer),
                       (PVOID*)&UnwindInfo)) != S_OK) {
        m_Services->Status(1, "Prol: Unable to read unwind info\n");
        return Status;
    }

    m_Services->Status(1, "  Unwind info has 0x%X codes\n",
                       UnwindInfo->CountOfCodes);

    while (Index < UnwindInfo->CountOfCodes) {

        m_Services->Status(1, "  %02X: Code %X offs %03X, RSP %I64X\n",
             Index, UnwindInfo->UnwindCode[Index].UnwindOp,
             UnwindInfo->UnwindCode[Index].CodeOffset,
             ContextRecord->Rsp);

        //
        // If the prologue offset is greater than the next unwind code offset,
        // then simulate the effect of the unwind code.
        //

        UnwindOp = UnwindInfo->UnwindCode[Index].UnwindOp;
        if (UnwindOp > AMD64_UWOP_PUSH_MACHFRAME) {
            m_Services->Status(1, "Prol: Invalid unwind op %X at index %X\n",
                 UnwindOp, Index);
            goto Fail;
        }

        OpInfo = UnwindInfo->UnwindCode[Index].OpInfo;
        if (PrologOffset >= UnwindInfo->UnwindCode[Index].CodeOffset) {
            switch (UnwindOp) {

                //
                // Push nonvolatile integer register.
                //
                // The operation information is the register number of the
                // register than was pushed.
                //

            case AMD64_UWOP_PUSH_NONVOL:
                IntegerAddress = ContextRecord->Rsp;
                if ((Status = m_Services->
                     ReadAllMemory(IntegerAddress,
                                   &IntegerRegister[OpInfo],
                                   sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory "
                                       "read failed at %I64X\n",
                                       UnwindOp, IntegerAddress);
                    goto Fail;
                }

                ContextRecord->Rsp += 8;
                break;

                //
                // Allocate a large sized area on the stack.
                //
                // The operation information determines if the size is
                // 16- or 32-bits.
                //

            case AMD64_UWOP_ALLOC_LARGE:
                Index += 1;
                FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset;
                if (OpInfo != 0) {
                    Index += 1;
                    FrameOffset += (UnwindInfo->UnwindCode[Index].FrameOffset << 16);
                } else {
                    // The 16-bit form is scaled.
                    FrameOffset *= 8;
                }

                ContextRecord->Rsp += FrameOffset;
                break;

                //
                // Allocate a small sized area on the stack.
                //
                // The operation information is the size of the unscaled
                // allocation size (8 is the scale factor) minus 8.
                //

            case AMD64_UWOP_ALLOC_SMALL:
                ContextRecord->Rsp += (OpInfo * 8) + 8;
                break;

                //
                // Establish the the frame pointer register.
                //
                // The operation information is not used.
                //

            case AMD64_UWOP_SET_FPREG:
                ContextRecord->Rsp = IntegerRegister[UnwindInfo->FrameRegister];
                ContextRecord->Rsp -= UnwindInfo->FrameOffset * 16;
                break;

                //
                // Save nonvolatile integer register on the stack using a
                // 16-bit displacment.
                //
                // The operation information is the register number.
                //

            case AMD64_UWOP_SAVE_NONVOL:
                Index += 1;
                FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset * 8;
                IntegerAddress = FrameBase + FrameOffset;
                if ((Status = m_Services->
                    ReadAllMemory(IntegerAddress,
                                  &IntegerRegister[OpInfo],
                                  sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory read "
                                       "failed at %I64X\n",
                                       UnwindOp, IntegerAddress);
                    goto Fail;
                }
                break;

                //
                // Save nonvolatile integer register on the stack using a
                // 32-bit displacment.
                //
                // The operation information is the register number.
                //

            case AMD64_UWOP_SAVE_NONVOL_FAR:
                Index += 2;
                FrameOffset = UnwindInfo->UnwindCode[Index - 1].FrameOffset;
                FrameOffset += UnwindInfo->UnwindCode[Index].FrameOffset << 16;
                IntegerAddress = FrameBase + FrameOffset;
                if ((Status = m_Services->
                     ReadAllMemory(IntegerAddress,
                                   &IntegerRegister[OpInfo],
                                   sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory read "
                                       "failed at %I64X\n",
                                       UnwindOp, IntegerAddress);
                    goto Fail;
                }
                break;

                //
                // Save a nonvolatile XMM(64) register on the stack using a
                // 16-bit displacement.
                //
                // The operation information is the register number.
                //

            case AMD64_UWOP_SAVE_XMM:
                Index += 1;
                FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset * 8;
                FloatingAddress = FrameBase + FrameOffset;
                FloatingRegister[OpInfo].High = 0;
                if ((Status = m_Services->
                     ReadAllMemory(FloatingAddress,
                                   &FloatingRegister[OpInfo].Low,
                                   sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory read "
                                       "failed at %I64X\n",
                                       UnwindOp, FloatingAddress);
                    goto Fail;
                }
                break;

                //
                // Save a nonvolatile XMM(64) register on the stack using a
                // 32-bit displacement.
                //
                // The operation information is the register number.
                //

            case AMD64_UWOP_SAVE_XMM_FAR:
                Index += 2;
                FrameOffset = UnwindInfo->UnwindCode[Index - 1].FrameOffset;
                FrameOffset += UnwindInfo->UnwindCode[Index].FrameOffset << 16;
                FloatingAddress = FrameBase + FrameOffset;
                FloatingRegister[OpInfo].High = 0;
                if ((Status = m_Services->
                     ReadAllMemory(FloatingAddress,
                                   &FloatingRegister[OpInfo].Low,
                                   sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory read "
                                       "failed at %I64X\n",
                                       UnwindOp, FloatingAddress);
                    goto Fail;
                }
                break;

                //
                // Save a nonvolatile XMM(128) register on the stack using a
                // 16-bit displacement.
                //
                // The operation information is the register number.
                //

            case AMD64_UWOP_SAVE_XMM128:
                Index += 1;
                FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset * 16;
                FloatingAddress = FrameBase + FrameOffset;
                if ((Status = m_Services->
                     ReadAllMemory(FloatingAddress,
                                   &FloatingRegister[OpInfo],
                                   sizeof(AMD64_M128))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory read "
                                       "failed at %I64X\n",
                                       UnwindOp, FloatingAddress);
                    goto Fail;
                }
                break;

                //
                // Save a nonvolatile XMM(128) register on the stack using a
                // 32-bit displacement.
                //
                // The operation information is the register number.
                //

            case AMD64_UWOP_SAVE_XMM128_FAR:
                Index += 2;
                FrameOffset = UnwindInfo->UnwindCode[Index - 1].FrameOffset;
                FrameOffset += UnwindInfo->UnwindCode[Index].FrameOffset << 16;
                FloatingAddress = FrameBase + FrameOffset;
                if ((Status = m_Services->
                     ReadAllMemory(FloatingAddress,
                                   &FloatingRegister[OpInfo],
                                   sizeof(AMD64_M128))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory read "
                                       "failed at %I64X\n",
                                       UnwindOp, FloatingAddress);
                    goto Fail;
                }
                break;

                //
                // Push a machine frame on the stack.
                //
                // The operation information determines whether the machine
                // frame contains an error code or not.
                //

            case AMD64_UWOP_PUSH_MACHFRAME:
                MachineFrame = TRUE;
                ReturnAddress = ContextRecord->Rsp;
                StackAddress = ContextRecord->Rsp + (3 * 8);
                if (OpInfo != 0) {
                    ReturnAddress += 8;
                    StackAddress +=  8;
                }

                m_RestartFrame = true;
                m_TrapAddr = ReturnAddress -
                    FIELD_OFFSET(AMD64_KTRAP_FRAME, Rip);

                if ((Status = m_Services->
                     ReadAllMemory(ReturnAddress,
                                   &ContextRecord->Rip,
                                   sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory "
                                       "read 1 failed at %I64X\n",
                                       UnwindOp, ReturnAddress);
                    goto Fail;
                }
                if ((Status = m_Services->
                     ReadAllMemory(StackAddress,
                                   &ContextRecord->Rsp,
                                   sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Prol: Op %X memory "
                                       "read 2 failed at %I64X\n",
                                       UnwindOp, StackAddress);
                    goto Fail;
                }
                break;

                //
                // Unused codes.
                //

            default:
                break;
            }

            Index += 1;

        } else {

            //
            // Skip this unwind operation by advancing the slot index by the
            // number of slots consumed by this operation.
            //

            Index += s_UnwindOpSlotTable[UnwindOp];

            //
            // Special case any unwind operations that can consume a variable
            // number of slots.
            //

            switch (UnwindOp) {

                //
                // A non-zero operation information indicates that an
                // additional slot is consumed.
                //

            case AMD64_UWOP_ALLOC_LARGE:
                if (OpInfo != 0) {
                    Index += 1;
                }

                break;

                //
                // No other special cases.
                //

            default:
                break;
            }
        }
    }

    //
    // If chained unwind information is specified, then recursively unwind
    // the chained information. Otherwise, determine the return address if
    // a machine frame was not encountered during the scan of the unwind
    // codes.
    //

    if ((UnwindInfo->Flags & AMD64_UNW_FLAG_CHAININFO) != 0) {

        _PIMAGE_RUNTIME_FUNCTION_ENTRY ChainEntry;

        Index = UnwindInfo->CountOfCodes;
        if ((Index & 1) != 0) {
            Index += 1;
        }

        // GetUnwindInfo looks for CHAININFO and reads
        // the trailing RUNTIME_FUNCTION so we can just
        // directly use the data sitting in UnwindInfo.
        ChainEntry = (_PIMAGE_RUNTIME_FUNCTION_ENTRY)
            &UnwindInfo->UnwindCode[Index];

        m_Services->Status(1, "  Chain with entry at %I64X\n",
             FunctionEntry->UnwindInfoAddress + ImageBase +
             (ULONG64)((PUCHAR)&UnwindInfo->UnwindCode[Index] -
                       (PUCHAR)UnwindInfo));

        Status = UnwindPrologue(ImageBase,
                                ControlPc,
                                FrameBase,
                                ChainEntry,
                                ContextRecord);

        FreeUnwindInfo(UnwindInfo, UnwindInfoBuffer);
        return Status;

    } else {
        FreeUnwindInfo(UnwindInfo, UnwindInfoBuffer);

        if (MachineFrame == FALSE) {
            if ((Status = m_Services->
                 ReadAllMemory(ContextRecord->Rsp,
                               &ContextRecord->Rip,
                               sizeof(ULONG64))) != S_OK) {
                return Status;
            }
            ContextRecord->Rsp += 8;
        }

        m_Services->Status(1, "Prol: Returning with RIP %I64X, RSP %I64X\n",
                           ContextRecord->Rip, ContextRecord->Rsp);
        return S_OK;
    }

 Fail:
    FreeUnwindInfo(UnwindInfo, UnwindInfoBuffer);
    m_Services->Status(1, "Prol: Unwind failed, 0x%08X\n", Status);
    return Status;
}

HRESULT
DbsX64StackUnwinder::VirtualUnwind(
    __in ULONG64 ImageBase,
    __in ULONG64 ControlPc,
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __inout PAMD64_CONTEXT ContextRecord,
    __out PULONG64 EstablisherFrame
    )

/*++

Routine Description:

    This function virtually unwinds the specified function by executing its
    prologue code backward or its epilogue code forward.

    If a context pointers record is specified, then the address where each
    nonvolatile registers is restored from is recorded in the appropriate
    element of the context pointers record.

Arguments:

    ImageBase - Supplies the base address of the image that contains the
        function being unwound.

    ControlPc - Supplies the address where control left the specified
        function.

    FunctionEntry - Supplies the address of the function table entry for the
        specified function.

    ContextRecord - Supplies the address of a context record.

    EstablisherFrame - Supplies a pointer to a variable that receives the
        the establisher frame pointer value.

--*/

{

    HRESULT Status;
    ULONG64 BranchTarget;
    LONG Displacement;
    ULONG FrameRegister;
    ULONG Index;
    LOGICAL InEpilogue;
    PULONG64 IntegerRegister;
    PUCHAR NextByte;
    _PIMAGE_RUNTIME_FUNCTION_ENTRY PrimaryFunctionEntry;
    ULONG PrologOffset;
    ULONG RegisterNumber;
    PAMD64_UNWIND_INFO UnwindInfo;
    ULONG64 UnwindInfoBuffer[8];
    ULONG Done;
    UCHAR InstrBuffer[32];
    ULONG InstrBytes;
    ULONG Bytes;
    ULONG UnwindFrameReg;

    //
    // If the specified function does not use a frame pointer, then the
    // establisher frame is the contents of the stack pointer. This may
    // not actually be the real establisher frame if control left the
    // function from within the prologue. In this case the establisher
    // frame may be not required since control has not actually entered
    // the function and prologue entries cannot refer to the establisher
    // frame before it has been established, i.e., if it has not been
    // established, then no save unwind codes should be encountered during
    // the unwind operation.
    //
    // If the specified function uses a frame pointer and control left the
    // function outside of the prologue or the unwind information contains
    // a chained information structure, then the establisher frame is the
    // contents of the frame pointer.
    //
    // If the specified function uses a frame pointer and control left the
    // function from within the prologue, then the set frame pointer unwind
    // code must be looked up in the unwind codes to detetermine if the
    // contents of the stack pointer or the contents of the frame pointer
    // should be used for the establisher frame. This may not actually be
    // the real establisher frame. In this case the establisher frame may
    // not be required since control has not actually entered the function
    // and prologue entries cannot refer to the establisher frame before it
    // has been established, i.e., if it has not been established, then no
    // save unwind codes should be encountered during the unwind operation.
    //
    // N.B. The correctness of these assumptions is based on the ordering of
    //      unwind codes.
    //

    if ((Status = GetUnwindInfo(ImageBase, FunctionEntry->UnwindInfoAddress,
                                true,
                                UnwindInfoBuffer, sizeof(UnwindInfoBuffer),
                                (PVOID*)&UnwindInfo)) != S_OK) {
        return Status;
    }

    PrologOffset = (ULONG)(ControlPc - (FunctionEntry->BeginAddress + ImageBase));
    UnwindFrameReg = UnwindInfo->FrameRegister;
    if (UnwindFrameReg == 0) {
        *EstablisherFrame = ContextRecord->Rsp;

    } else if ((PrologOffset >= UnwindInfo->SizeOfProlog) ||
               ((UnwindInfo->Flags & AMD64_UNW_FLAG_CHAININFO) != 0)) {
        *EstablisherFrame = (&ContextRecord->Rax)[UnwindFrameReg];
        *EstablisherFrame -= UnwindInfo->FrameOffset * 16;

    } else {

        // Read all the data.
        if ((Status = GetUnwindInfo(ImageBase,
                                    FunctionEntry->UnwindInfoAddress,
                                    false,
                                    UnwindInfoBuffer,
                                    sizeof(UnwindInfoBuffer),
                                    (PVOID*)&UnwindInfo)) != S_OK) {
            return Status;
        }

        Index = 0;
        while (Index < UnwindInfo->CountOfCodes) {
            if (UnwindInfo->UnwindCode[Index].UnwindOp == AMD64_UWOP_SET_FPREG) {
                break;
            }

            Index += 1;
        }

        if (PrologOffset >= UnwindInfo->UnwindCode[Index].CodeOffset) {
            *EstablisherFrame = (&ContextRecord->Rax)[UnwindFrameReg];
            *EstablisherFrame -= UnwindInfo->FrameOffset * 16;

        } else {
            *EstablisherFrame = ContextRecord->Rsp;
        }

        FreeUnwindInfo(UnwindInfo, UnwindInfoBuffer);
    }

    if ((Status = m_Services->
         ReadMemory(ControlPc, InstrBuffer, sizeof(InstrBuffer),
                    &InstrBytes)) != S_OK) {
        m_Services->Status(1, "Unable to read instruction stream at %I64X\n",
                           ControlPc);

        // We need the code to look for epilogue ops.
        // It's very rare to be stopped in an epilogue when
        // getting a stack trace, so if we can't read the
        // code just assume we aren't in an epilogue.
        InstrBytes = 0;
    }

    //
    // If the point at which control left the specified function is in an
    // epilogue, then emulate the execution of the epilogue forward and
    // return no exception handler.
    //

    IntegerRegister = &ContextRecord->Rax;
    NextByte = InstrBuffer;
    Bytes = InstrBytes;

    //
    // Check for one of:
    //
    //   add rsp, imm8
    //       or
    //   add rsp, imm32
    //       or
    //   lea rsp, -disp8[fp]
    //       or
    //   lea rsp, -disp32[fp]
    //

    if (Bytes >= 4 &&
        (NextByte[0] == SIZE64_PREFIX) &&
        (NextByte[1] == ADD_IMM8_OP) &&
        (NextByte[2] == 0xc4)) {

        //
        // add rsp, imm8.
        //

        NextByte += 4;
        Bytes -= 4;

    } else if (Bytes >= 7 &&
               (NextByte[0] == SIZE64_PREFIX) &&
               (NextByte[1] == ADD_IMM32_OP) &&
               (NextByte[2] == 0xc4)) {

        //
        // add rsp, imm32.
        //

        NextByte += 7;
        Bytes -= 7;

    } else if (Bytes >= 4 &&
               ((NextByte[0] & 0xf8) == SIZE64_PREFIX) &&
               (NextByte[1] == LEA_OP)) {

        FrameRegister = ((NextByte[0] & 0x7) << 3) | (NextByte[2] & 0x7);
        if ((FrameRegister != 0) &&
            (FrameRegister == UnwindFrameReg)) {
            if ((NextByte[2] & 0xf8) == 0x60) {

                //
                // lea rsp, disp8[fp].
                //

                NextByte += 4;
                Bytes -= 4;

            } else if (Bytes >= 7 &&
                       (NextByte[2] &0xf8) == 0xa0) {

                //
                // lea rsp, disp32[fp].
                //

                NextByte += 7;
                Bytes -= 7;
            }
        }
    }

    //
    // Check for any number of:
    //
    //   pop nonvolatile-integer-register[0..15].
    //

    while (TRUE) {
        if (Bytes >= 1 &&
            (NextByte[0] & 0xf8) == POP_OP) {
            NextByte += 1;
            Bytes -= 1;

        } else if (Bytes >= 2 &&
                   IS_REX_PREFIX(NextByte[0]) &&
                   ((NextByte[1] & 0xf8) == POP_OP)) {

            NextByte += 2;
            Bytes -= 2;

        } else {
            break;
        }
    }

    //
    // If the next instruction is a return or an appropriate jump, then
    // control is currently in an epilogue and execution of the epilogue
    // should be emulated. Otherwise, execution is not in an epilogue and
    // the prologue should be unwound.
    //

    InEpilogue = FALSE;
    if ((Bytes >= 1 &&
         ((NextByte[0] == RET_OP) ||
          (NextByte[0] == RET_OP_2))) ||
        (Bytes >= 2 &&
         ((NextByte[0] == REP_PREFIX) && (NextByte[1] == RET_OP)))) {

        //
        // A return is an unambiguous indication of an epilogue.
        //

        InEpilogue = TRUE;

    } else if ((Bytes >= 2 && NextByte[0] == JMP_IMM8_OP) ||
               (Bytes >= 5 && NextByte[0] == JMP_IMM32_OP)) {

        //
        // An unconditional branch to a target that is equal to the start of
        // or outside of this routine is logically a call to another function.
        //

        BranchTarget = (ULONG64)(NextByte - InstrBuffer) + ControlPc - ImageBase;
        if (NextByte[0] == JMP_IMM8_OP) {
            BranchTarget += 2 + (CHAR)NextByte[1];
        } else {
            BranchTarget += 5 + *((LONG UNALIGNED *)&NextByte[1]);
        }

        //
        // Determine whether the branch target refers to code within this
        // function. If not, then it is an epilogue indicator.
        //
        // A branch to the start of self implies a recursive call, so
        // is treated as an epilogue.
        //

        if (BranchTarget < FunctionEntry->BeginAddress ||
            BranchTarget >= FunctionEntry->EndAddress) {

            _IMAGE_RUNTIME_FUNCTION_ENTRY PrimaryEntryBuffer;

            //
            // The branch target is outside of the region described by
            // this function entry.  See whether it is contained within
            // an indirect function entry associated with this same
            // function.
            //
            // If not, then the branch target really is outside of
            // this function.
            //

            PrimaryFunctionEntry =
                SameFunction(FunctionEntry,
                             ImageBase,
                             BranchTarget + ImageBase,
                             &PrimaryEntryBuffer);

            if ((PrimaryFunctionEntry == NULL) ||
                (BranchTarget == PrimaryFunctionEntry->BeginAddress)) {

                InEpilogue = TRUE;
            }

        } else if ((BranchTarget == FunctionEntry->BeginAddress) &&
                   ((UnwindInfo->Flags & AMD64_UNW_FLAG_CHAININFO) == 0)) {

            InEpilogue = TRUE;
        }

    } else if (Bytes >= 2 &&
               (NextByte[0] == JMP_IND_OP) && (NextByte[1] == 0x25)) {

        //
        // An unconditional jump indirect.
        //
        // This is a jmp outside of the function, probably a tail call
        // to an import function.
        //

        InEpilogue = TRUE;

    } else if (Bytes >= 3 &&
               ((NextByte[0] & 0xf8) == SIZE64_PREFIX) &&
               (NextByte[1] == 0xff) &&
               (NextByte[2] & 0x38) == 0x20) {

        //
        // This is an indirect jump opcode: 0x48 0xff /4.  The 64-bit
        // flag (REX.W) is always redundant here, so its presence is
        // overloaded to indicate a branch out of the function - a tail
        // call.
        //
        // Such an opcode is an unambiguous epilogue indication.
        //

        InEpilogue = TRUE;
    }

    if (InEpilogue != FALSE) {
        NextByte = InstrBuffer;
        Bytes = InstrBytes;

        //
        // Emulate one of (if any):
        //
        //   add rsp, imm8
        //       or
        //   add rsp, imm32
        //       or
        //   lea rsp, disp8[frame-register]
        //       or
        //   lea rsp, disp32[frame-register]
        //

        if (Bytes >= 1 &&
            (NextByte[0] & 0xf8) == SIZE64_PREFIX) {

            if (Bytes >= 4 &&
                NextByte[1] == ADD_IMM8_OP) {

                //
                // add rsp, imm8.
                //

                ContextRecord->Rsp += (CHAR)NextByte[3];
                NextByte += 4;
                Bytes -= 4;

            } else if (Bytes >= 7 &&
                       NextByte[1] == ADD_IMM32_OP) {

                //
                // add rsp, imm32.
                //

                Displacement = NextByte[3] | (NextByte[4] << 8);
                Displacement |= (NextByte[5] << 16) | (NextByte[6] << 24);
                ContextRecord->Rsp += Displacement;
                NextByte += 7;
                Bytes -= 7;

            } else if (Bytes >= 4 &&
                       NextByte[1] == LEA_OP) {
                if ((NextByte[2] & 0xf8) == 0x60) {

                    //
                    // lea rsp, disp8[frame-register].
                    //

                    ContextRecord->Rsp = IntegerRegister[FrameRegister];
                    ContextRecord->Rsp += (CHAR)NextByte[3];
                    NextByte += 4;
                    Bytes -= 4;

                } else if (Bytes >= 7 &&
                           (NextByte[2] & 0xf8) == 0xa0) {

                    //
                    // lea rsp, disp32[frame-register].
                    //

                    Displacement = NextByte[3] | (NextByte[4] << 8);
                    Displacement |= (NextByte[5] << 16) | (NextByte[6] << 24);
                    ContextRecord->Rsp = IntegerRegister[FrameRegister];
                    ContextRecord->Rsp += Displacement;
                    NextByte += 7;
                    Bytes -= 7;
                }
            }
        }

        //
        // Emulate any number of (if any):
        //
        //   pop nonvolatile-integer-register.
        //

        while (TRUE) {
            if (Bytes >= 1 &&
                (NextByte[0] & 0xf8) == POP_OP) {

                //
                // pop nonvolatile-integer-register[0..7]
                //

                RegisterNumber = NextByte[0] & 0x7;
                if ((Status = m_Services->
                    ReadAllMemory(ContextRecord->Rsp,
                                  &IntegerRegister[RegisterNumber],
                                  sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Unable to read stack at %I64X\n",
                         ContextRecord->Rsp);
                    return Status;
                }
                ContextRecord->Rsp += 8;
                NextByte += 1;
                Bytes -= 1;

            } else if (Bytes >= 2 &&
                       IS_REX_PREFIX(NextByte[0]) &&
                       (NextByte[1] & 0xf8) == POP_OP) {

                //
                // pop nonvolatile-integer-register[8..15]
                //

                RegisterNumber = ((NextByte[0] & 1) << 3) | (NextByte[1] & 0x7);
                if ((Status = m_Services->
                     ReadAllMemory(ContextRecord->Rsp,
                                   &IntegerRegister[RegisterNumber],
                                   sizeof(ULONG64))) != S_OK) {
                    m_Services->Status(1, "Unable to read stack at %I64X\n",
                         ContextRecord->Rsp);
                    return Status;
                }
                ContextRecord->Rsp += 8;
                NextByte += 2;
                Bytes -= 2;

            } else {
                break;
            }
        }

        //
        // Emulate return and return null exception handler.
        //
        // Note: this instruction might in fact be a jmp, however
        //       we want to emulate a return regardless.
        //

        if ((Status = m_Services->
            ReadAllMemory(ContextRecord->Rsp,
                          &ContextRecord->Rip,
                          sizeof(ULONG64))) != S_OK) {
            m_Services->Status(1, "Unable to read stack at %I64X\n",
                 ContextRecord->Rsp);
            return Status;
        }
        ContextRecord->Rsp += 8;
        return S_OK;
    }

    //
    // Control left the specified function outside an epilogue. Unwind the
    // subject function and any chained unwind information.
    //

    return UnwindPrologue(ImageBase,
                          ControlPc,
                          *EstablisherFrame,
                          FunctionEntry,
                          ContextRecord);
}

ULONG64
DbsX64StackUnwinder::LookupPrimaryUnwindInfo(
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __in ULONG64 ImageBase,
    __out _PIMAGE_RUNTIME_FUNCTION_ENTRY PrimaryEntry
    )

/*++

Routine Description:

    This function determines whether the supplied function entry is a primary
    function entry or a chained function entry. If it is a chained function
    entry, the unwind information associated with the primary function entry
    is returned.

Arguments:

    FunctionEntry - Supplies a pointer to the function entry for which the
        associated primary function entry will be located.

    ImageBase - Supplies the base address of the image containing the
        supplied function entry.

    PrimaryEntry - Supplies the address of a variable that receives a pointer
        to the primary function entry.

Return Value:

    A pointer to the unwind information for the primary function entry is
    returned as the function value.

--*/

{

    ULONG Index;
    ULONG64 UnwindInfoBuffer[32];
    PAMD64_UNWIND_INFO UnwindInfo;
    ULONG UnwindRel;
    ULONG64 UnwindAbs;

    //
    // Locate the unwind information and determine whether it is chained.
    // If the unwind information is chained, then locate the parent function
    // entry and loop again.
    //

    UnwindRel = FunctionEntry->UnwindInfoAddress;
    // Copy the function entry before it becomes invalid.
    *PrimaryEntry = *FunctionEntry;

    do {
        UnwindAbs = ImageBase + UnwindRel;
        if (GetUnwindInfo(ImageBase, UnwindRel,
                          false,
                          UnwindInfoBuffer, sizeof(UnwindInfoBuffer),
                          (PVOID*)&UnwindInfo) != S_OK ||
            (UnwindInfo->Flags & AMD64_UNW_FLAG_CHAININFO) == 0) {
            break;
        }

        Index = UnwindInfo->CountOfCodes;
        if ((Index & 1) != 0) {
            Index += 1;
        }

        FunctionEntry = (_PIMAGE_RUNTIME_FUNCTION_ENTRY)
            &UnwindInfo->UnwindCode[Index];
        UnwindRel = FunctionEntry->UnwindInfoAddress;

        // Copy the function entry before it becomes invalid.
        *PrimaryEntry = *FunctionEntry;

        FreeUnwindInfo(UnwindInfo, UnwindInfoBuffer);

    } while (TRUE);

    return UnwindAbs;
}

_PIMAGE_RUNTIME_FUNCTION_ENTRY
DbsX64StackUnwinder::SameFunction(
    __in _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
    __in ULONG64 ImageBase,
    __in ULONG64 ControlPc,
    __out _PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionReturnBuffer
    )

/*++

Routine Description:

    This function determines whether the address supplied by ControlPc lies
    anywhere within the function associated with FunctionEntry.

Arguments:

    FunctionEntry - Supplies a pointer to a function entry (primary or chained)
        associated with the function.

    ImageBase - Supplies the base address of the image containing the supplied
        function entry.

    ControlPc - Supplies the address that will be tested for inclusion within
        the function associated with FunctionEntry.

Return Value:

    If the address of the unwind information for the specified function is
    equal to the address of the unwind information for the control PC, then
    a pointer to a function table entry that describes the primary function
    table entry is returned as the function value. Otherwise, NULL is returned.

--*/

{

    _IMAGE_RUNTIME_FUNCTION_ENTRY TargetFunctionEntry;
    ULONG64 TargetImageBase;
    ULONG64 UnwindInfo1;
    ULONG64 UnwindInfo2;

    //
    // Find the unwind information referenced by the primary function entry
    // associated with the specified function entry.
    //

    UnwindInfo1 = LookupPrimaryUnwindInfo(FunctionEntry, ImageBase,
                                          FunctionReturnBuffer);

    //
    // Determine the function entry containing the control Pc and similarly
    // resolve it's primary function entry.
    //

    if (m_Services->GetModuleBase(ControlPc, &TargetImageBase) != S_OK ||
        m_Services->GetFunctionEntry(ControlPc,
                                     &TargetFunctionEntry,
                                     sizeof(TargetFunctionEntry)) != S_OK) {
        return NULL;
    }

    UnwindInfo2 = LookupPrimaryUnwindInfo(&TargetFunctionEntry,
                                          TargetImageBase,
                                          FunctionReturnBuffer);

    //
    // If the address of the two sets of unwind information are equal, then
    // return the address of the primary function entry. Otherwise, return
    // NULL.
    //

    if (UnwindInfo1 == UnwindInfo2) {
        return FunctionReturnBuffer;

    } else {
        return NULL;
    }
}

//----------------------------------------------------------------------------
//
// DbsX64StackUnwinder.
//
//----------------------------------------------------------------------------

#define DBHX64_SAVE_TRAP(_DbhFrame) ((_DbhFrame)->Reserved[0])

//
// Flags word.
//

#define DBHX64_IS_RESTART_FLAG    (0x1UI64)

#define DBHX64_GET_IS_RESTART(_DbhFrame) \
    ((((_DbhFrame)->Reserved[2]) & DBHX64_IS_RESTART_FLAG) != 0)
#define DBHX64_SET_IS_RESTART(_DbhFrame, _IsRestart) \
    ((_DbhFrame)->Reserved[2] = \
     (((_DbhFrame)->Reserved[2]) & ~DBHX64_IS_RESTART_FLAG) | \
      ((_IsRestart) ? DBHX64_IS_RESTART_FLAG : 0))

DbsX64StackUnwinder::DbsX64StackUnwinder(__in_opt DbsStackServices* Services)
    : DbsStackUnwinder(Services, "x64", IMAGE_FILE_MACHINE_AMD64,
                       sizeof(m_Context),
                       sizeof(_IMAGE_RUNTIME_FUNCTION_ENTRY),
                       sizeof(AMD64_UNWIND_INFO), 16, 8, 1)
{
    m_ContextBuffer = &m_Context;
}

HRESULT
DbsX64StackUnwinder::Unwind(void)
{
    HRESULT Status;

    ClearUnwindDerived();

    if (SUCCEEDED(Status = BaseUnwind()))
    {
        return Status;
    }

    //
    // Unable to do a normal unwind, so check for
    // alternate transitions like kernel/user boundaries.
    // If this fails just return the original error
    // as that's more likely to be interesting.
    //

    DWORD64 ImageBase;
    _IMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry;
    DWORD64 StackPointer;

    if (UnwindNtKernelCallback(&ImageBase,
                               &FunctionEntry,
                               sizeof(FunctionEntry),
                               &StackPointer) != S_OK)
    {
        return Status;
    }

    m_InstructionPointer = ImageBase + FunctionEntry.BeginAddress;
    m_CallPointer = m_InstructionPointer;
    m_Context.Rip = m_InstructionPointer;
    m_StackPointer = StackPointer;
    m_Context.Rsp = m_StackPointer;
    m_RestartFrame = true;

    return S_OK;
}

DWORD
DbsX64StackUnwinder::
GetFullUnwindInfoSize(__in PVOID InfoHeader)
{
    PAMD64_UNWIND_INFO UnwindInfo = (PAMD64_UNWIND_INFO)InfoHeader;

    DWORD UnwindInfoSize = FIELD_OFFSET(AMD64_UNWIND_INFO, UnwindCode) +
        UnwindInfo->CountOfCodes * sizeof(AMD64_UNWIND_CODE);

    // An extra alignment code and function entry may be added on to handle
    // the chained info case where the chain function entry is just
    // beyond the end of the normal code array.
    if ((UnwindInfo->Flags & AMD64_UNW_FLAG_CHAININFO) != 0)
    {
        if ((UnwindInfo->CountOfCodes & 1) != 0)
        {
            UnwindInfoSize += sizeof(AMD64_UNWIND_CODE);
        }
        UnwindInfoSize += sizeof(_IMAGE_RUNTIME_FUNCTION_ENTRY);
    }

    return UnwindInfoSize;
}

HRESULT
DbsX64StackUnwinder::DbhStart(__inout LPSTACKFRAME64 StackFrame,
                              __in DWORD DbhVersion,
                              __in_bcount(DbhStorageBytes) PVOID DbhStorage,
                              __in DWORD DbhStorageBytes,
                              __inout PVOID Context)
{
    HRESULT Status;

    if ((StackFrame->AddrPC.Offset &&
         StackFrame->AddrPC.Mode != AddrModeFlat) ||
        (StackFrame->AddrStack.Offset &&
         StackFrame->AddrStack.Mode != AddrModeFlat) ||
        (StackFrame->AddrFrame.Offset &&
         StackFrame->AddrFrame.Mode != AddrModeFlat))
    {
        return E_INVALIDARG;
    }

    if ((Status = DbsStackUnwinder::
         DbhStart(StackFrame, DbhVersion, DbhStorage, DbhStorageBytes,
                  Context)) != S_OK)
    {
        return Status;
    }

    // dbghelp doesn't give a context size so we
    // have to assume the buffer is large enough.
    memcpy(&m_Context, Context, sizeof(m_Context));

    //
    // Override context values from the stack frame if necessary.
    //

    if (StackFrame->AddrPC.Offset)
    {
        m_Context.Rip = StackFrame->AddrPC.Offset;
    }
    if (StackFrame->AddrStack.Offset)
    {
        m_Context.Rsp = StackFrame->AddrStack.Offset;
    }
    if (StackFrame->AddrFrame.Offset)
    {
        m_Context.Rbp = StackFrame->AddrFrame.Offset;
    }
    UpdateAbstractPointers();
    m_CallPointer = m_InstructionPointer;

    SetRestart();
    return S_OK;
}

HRESULT
DbsX64StackUnwinder::
DbhContinue(__inout LPSTACKFRAME64 StackFrame,
            __in DWORD DbhVersion,
            __in_bcount(DbhStorageBytes) PVOID DbhStorage,
            __in DWORD DbhStorageBytes,
            __inout PVOID Context)
{
    HRESULT Status;

    if ((Status = DbsStackUnwinder::
         DbhContinue(StackFrame, DbhVersion,
                     DbhStorage, DbhStorageBytes,
                     Context)) != S_OK)
    {
        return Status;
    }

    if (DBHX64_GET_IS_RESTART(StackFrame))
    {
        m_RestartFrame = true;
        // The base DbhContinue always assumes it
        // isn't a restart frame, so override it.
        m_CallPointer = m_InstructionPointer;
    }

    return Status;
}

HRESULT
DbsX64StackUnwinder::DbhUpdatePreUnwind(__inout LPSTACKFRAME64 StackFrame)
{
    HRESULT Status;

    if ((Status = DbsStackUnwinder::DbhUpdatePreUnwind(StackFrame)) != S_OK)
    {
        return Status;
    }

    DBHX64_SET_IS_RESTART(StackFrame, m_RestartFrame);
    return S_OK;
}

HRESULT
DbsX64StackUnwinder::DbhUpdatePostUnwind(__inout LPSTACKFRAME64 StackFrame,
                                         __in HRESULT UnwindStatus)
{
    HRESULT Status;

    if ((Status = DbsStackUnwinder::DbhUpdatePostUnwind(StackFrame,
                                                        UnwindStatus)) != S_OK)
    {
        return Status;
    }

    // The frame pointer is an artificial value set
    // to a pointer below the return address.  This
    // matches an RBP-chain style of frame while
    // also allowing easy access to the return
    // address and homed arguments above it.
    StackFrame->AddrFrame.Offset = m_FramePointer;

    DBHX64_SAVE_TRAP(StackFrame) = m_TrapAddr;
    return S_OK;
}

void
DbsX64StackUnwinder::UpdateAbstractPointers(void)
{
    m_InstructionPointer = m_Context.Rip;
    m_StackPointer = m_Context.Rsp;
    m_FramePointer = m_Context.Rbp;
}

HRESULT
DbsX64StackUnwinder::BaseUnwind(void)
{
    HRESULT Status;
    _IMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry;

    Status = m_Services->GetFunctionEntry(m_CallPointer,
                                          &FunctionEntry,
                                          sizeof(FunctionEntry));
    if (Status == S_OK)
    {
        DWORD64 ImageBase;
        DWORD64 EstablisherFrame;

        //
        // The return value coming out of mainCRTStartup is set by some
        // run-time routine to be 0; this serves to cause an error if someone
        // actually does a return from the mainCRTStartup frame.
        //

        if ((Status = m_Services->
             GetModuleBase(m_Context.Rip, &ImageBase)) != S_OK ||
            (Status = VirtualUnwind(ImageBase,
                                    m_Context.Rip,
                                    &FunctionEntry,
                                    &m_Context,
                                    &EstablisherFrame)) != S_OK)
        {
            return Status;
        }

        DWORD64 OldIp = m_InstructionPointer;

        UpdateAbstractPointers();
        UpdateCallPointer();
        m_FramePointer = m_StackPointer - 2 * sizeof(DWORD64);

        // Check for end frame.
        if (m_Context.Rip == 0 ||
            (m_Context.Rip == OldIp &&
             EstablisherFrame == m_Context.Rsp))
        {
            return S_FALSE;
        }
    }
    else if (Status == E_NOINTERFACE)
    {
        //
        // If there's no function entry for a function
        // we assume that it's a leaf and that RSP points
        // directly to the return address.
        //

        m_Services->Status(1, "Leaf %I64X RSP %I64X\n",
                           m_Context.Rip, m_Context.Rsp);

        if ((Status = m_Services->
             ReadAllMemory(m_Context.Rsp, &m_Context.Rip,
                           sizeof(m_Context.Rip))) != S_OK)
        {
            return Status;
        }

        // Update the context values to what they should be in
        // the caller.
        m_Context.Rsp += sizeof(m_Context.Rip);
        UpdateAbstractPointers();
        m_CallPointer = m_InstructionPointer - 1;
        m_FramePointer = m_StackPointer - 2 * sizeof(DWORD64);
    }
    else
    {
        return Status;
    }

    m_FrameIndex++;
    if (!m_RestartFrame)
    {
        AdjustForNoReturn(&m_InstructionPointer);
    }
    return S_OK;
}


text:
package com.steve.creact.powerfuladapter.presentation;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;

import com.steve.creact.library.adapter.CommonRecyclerAdapter;
import com.steve.creact.library.display.CommonDisplayBean;
import com.steve.creact.library.display.DisplayBean;
import com.steve.creact.powerfuladapter.R;
import com.steve.creact.powerfuladapter.data.Book;
import com.steve.creact.powerfuladapter.data.Category;
import com.steve.creact.powerfuladapter.data.MockCategory;
import com.steve.creact.powerfuladapter.presentation.viewholder.ICategory;
import com.steve.creact.powerfuladapter.presentation.viewholder.databean.BookTitleBean;
import com.steve.creact.powerfuladapter.presentation.viewholder.databean.CategoryBean;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class BaseListActivity extends AppCompatActivity {

    protected RecyclerView recyclerView;
    protected CommonRecyclerAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
        initData();
    }

    /**
     * Convert normal DataSet to DisplayBeans
     * If the data set which  returned by the server in the same order as in the list on ui,
     * this process will be easy
     */
    protected void initData() {
        //fake data
        Map<ICategory, List<Book>> sourceData = fetchSourceData();
        //display beans
        List<DisplayBean> displayBeans = new ArrayList<>(20);

        //Add a ProgressBar DisplayBean to show a ProgressBar in the top of the list
        CommonDisplayBean progressBean = new CommonDisplayBean(R.layout.item_progress);
        displayBeans.add(progressBean);

        //add categories and books to the list
        for (Iterator<Map.Entry<ICategory, List<Book>>> iterator = sourceData.entrySet().iterator(); iterator.hasNext(); ) {
            Map.Entry<ICategory, List<Book>> entry = iterator.next();
            ICategory category = entry.getKey();
            //add category to the list
            displayBeans.add(new CategoryBean(category));
            List<Book> books = entry.getValue();
            //add books to the category
            if (category != null && books != null) {
                for (Book book : books) {
                    BookTitleBean bookTitleBean = new BookTitleBean(book);
                    displayBeans.add(bookTitleBean);
                }
            }
        }
        //load data and show data in the list
        adapter.loadData(displayBeans);
    }

    protected void initViews() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        recyclerView = (RecyclerView) findViewById(R.id.recycler);
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        adapter = getAdapter();
        recyclerView.setAdapter(adapter);
    }

    protected CommonRecyclerAdapter getAdapter() {
        return new CommonRecyclerAdapter();
    }

    //fake data
    private Map<ICategory, List<Book>> fetchSourceData() {
        Map<ICategory, List<Book>> result = new LinkedHashMap<>();
        for (int i = 0; i < 5; i++) {
            ICategory category = i == 0 ? new MockCategory() : new Category(i, "category" + i);
            List<Book> books = new ArrayList<>(10);
            for (int j = 0; j < 10; j++) {
                Book book = new Book(j + 1, "book" + j, (200.5f + j), 100);
                books.add(book);
            }
            result.put(category, books);
        }
        return result;
    }

}


text:
class String
  def to_slug
    self.gsub("'", "").parameterize
  end
end


text:
"""Utility methods for working with WSGI servers."""

import sys

import eventlet
import eventlet.wsgi
import greenlet
from paste import deploy
import routes.middleware
import webob.dec
import webob.exc

from nova import exception
from nova import flags
from nova import log as logging
from nova import utils

FLAGS = flags.FLAGS
LOG = logging.getLogger(__name__)

class Server(object):
    """Server class to manage a WSGI server, serving a WSGI application."""

    default_pool_size = 1000

    def __init__(self, name, app, host=None, port=None, pool_size=None,
                       protocol=eventlet.wsgi.HttpProtocol):
        """Initialize, but do not start, a WSGI server.

        :param name: Pretty name for logging.
        :param app: The WSGI application to serve.
        :param host: IP address to serve the application.
        :param port: Port number to server the application.
        :param pool_size: Maximum number of eventlets to spawn concurrently.
        :returns: None

        """
        self.name = name
        self.app = app
        self.host = host or "0.0.0.0"
        self.port = port or 0
        self._server = None
        self._tcp_server = None
        self._socket = None
        self._protocol = protocol
        self._pool = eventlet.GreenPool(pool_size or self.default_pool_size)
        self._logger = logging.getLogger("eventlet.wsgi.server")
        self._wsgi_logger = logging.WritableLogger(self._logger)

    def _start(self):
        """Run the blocking eventlet WSGI server.

        :returns: None

        """
        eventlet.wsgi.server(self._socket,
                             self.app,
                             protocol=self._protocol,
                             custom_pool=self._pool,
                             log=self._wsgi_logger)

    def start(self, backlog=128):
        """Start serving a WSGI application.

        :param backlog: Maximum number of queued connections.
        :returns: None
        :raises: nova.exception.InvalidInput

        """
        if backlog < 1:
            raise exception.InvalidInput(
                    reason='The backlog must be more than 1')
        self._socket = eventlet.listen((self.host, self.port), backlog=backlog)
        self._server = eventlet.spawn(self._start)
        (self.host, self.port) = self._socket.getsockname()
        LOG.info(_("Started %(name)s on %(host)s:%(port)s") % self.__dict__)

    def stop(self):
        """Stop this server.

        This is not a very nice action, as currently the method by which a
        server is stopped is by killing it's eventlet.

        :returns: None

        """
        LOG.info(_("Stopping WSGI server."))
        self._server.kill()
        if self._tcp_server is not None:
            LOG.info(_("Stopping raw TCP server."))
            self._tcp_server.kill()

    def start_tcp(self, listener, port, host='0.0.0.0', key=None, backlog=128):
        """Run a raw TCP server with the given application."""
        arg0 = sys.argv[0]
        LOG.info(_('Starting TCP server %(arg0)s on %(host)s:%(port)s')
                 % locals())
        socket = eventlet.listen((host, port), backlog=backlog)
        self._tcp_server = self._pool.spawn_n(self._run_tcp, listener, socket)

    def wait(self):
        """Block, until the server has stopped.

        Waits on the server's eventlet to finish, then returns.

        :returns: None

        """
        try:
            self._server.wait()
        except greenlet.GreenletExit:
            LOG.info(_("WSGI server has stopped."))

    def _run_tcp(self, listener, socket):
        """Start a raw TCP server in a new green thread."""
        while True:
            try:
                new_sock, address = socket.accept()
                self._pool.spawn_n(listener, new_sock)
            except (SystemExit, KeyboardInterrupt):
                pass

class Request(webob.Request):
    pass

class Application(object):
    """Base WSGI application wrapper. Subclasses need to implement __call__."""

    @classmethod
    def factory(cls, global_config, **local_config):
        """Used for paste app factories in paste.deploy config files.

        Any local configuration (that is, values under the [app:APPNAME]
        section of the paste config) will be passed into the `__init__` method
        as kwargs.

        A hypothetical configuration would look like:

            [app:wadl]
            latest_version = 1.3
            paste.app_factory = nova.api.fancy_api:Wadl.factory

        which would result in a call to the `Wadl` class as

            import nova.api.fancy_api
            fancy_api.Wadl(latest_version='1.3')

        You could of course re-implement the `factory` method in subclasses,
        but using the kwarg passing it shouldn't be necessary.

        """
        return cls(**local_config)

    def __call__(self, environ, start_response):
        r"""Subclasses will probably want to implement __call__ like this:

        @webob.dec.wsgify(RequestClass=Request)
        def __call__(self, req):
          # Any of the following objects work as responses:

          # Option 1: simple string
          res = 'message\n'

          # Option 2: a nicely formatted HTTP exception page
          res = exc.HTTPForbidden(detail='Nice try')

          # Option 3: a webob Response object (in case you need to play with
          # headers, or you want to be treated like an iterable, or or or)
          res = Response();
          res.app_iter = open('somefile')

          # Option 4: any wsgi app to be run next
          res = self.application

          # Option 5: you can get a Response object for a wsgi app, too, to
          # play with headers etc
          res = req.get_response(self.application)

          # You can then just return your response...
          return res
          # ... or set req.response and return None.
          req.response = res

        See the end of http://pythonpaste.org/webob/modules/dec.html
        for more info.

        """
        raise NotImplementedError(_('You must implement __call__'))

class Middleware(Application):
    """Base WSGI middleware.

    These classes require an application to be
    initialized that will be called next.  By default the middleware will
    simply call its wrapped app, or you can override __call__ to customize its
    behavior.

    """

    @classmethod
    def factory(cls, global_config, **local_config):
        """Used for paste app factories in paste.deploy config files.

        Any local configuration (that is, values under the [filter:APPNAME]
        section of the paste config) will be passed into the `__init__` method
        as kwargs.

        A hypothetical configuration would look like:

            [filter:analytics]
            redis_host = 127.0.0.1
            paste.filter_factory = nova.api.analytics:Analytics.factory

        which would result in a call to the `Analytics` class as

            import nova.api.analytics
            analytics.Analytics(app_from_paste, redis_host='127.0.0.1')

        You could of course re-implement the `factory` method in subclasses,
        but using the kwarg passing it shouldn't be necessary.

        """
        def _factory(app):
            return cls(app, **local_config)
        return _factory

    def __init__(self, application):
        self.application = application

    def process_request(self, req):
        """Called on each request.

        If this returns None, the next application down the stack will be
        executed. If it returns a response then that response will be returned
        and execution will stop here.

        """
        return None

    def process_response(self, response):
        """Do whatever you'd like to the response."""
        return response

    @webob.dec.wsgify(RequestClass=Request)
    def __call__(self, req):
        response = self.process_request(req)
        if response:
            return response
        response = req.get_response(self.application)
        return self.process_response(response)

class Debug(Middleware):
    """Helper class for debugging a WSGI application.

    Can be inserted into any WSGI application chain to get information
    about the request and response.

    """

    @webob.dec.wsgify(RequestClass=Request)
    def __call__(self, req):
        print ('*' * 40) + ' REQUEST ENVIRON'
        for key, value in req.environ.items():
            print key, '=', value
        print
        resp = req.get_response(self.application)

        print ('*' * 40) + ' RESPONSE HEADERS'
        for (key, value) in resp.headers.iteritems():
            print key, '=', value
        print

        resp.app_iter = self.print_generator(resp.app_iter)

        return resp

    @staticmethod
    def print_generator(app_iter):
        """Iterator that prints the contents of a wrapper string."""
        print ('*' * 40) + ' BODY'
        for part in app_iter:
            sys.stdout.write(part)
            sys.stdout.flush()
            yield part
        print

class Router(object):
    """WSGI middleware that maps incoming requests to WSGI apps."""

    def __init__(self, mapper):
        """Create a router for the given routes.Mapper.

        Each route in `mapper` must specify a 'controller', which is a
        WSGI app to call.  You'll probably want to specify an 'action' as
        well and have your controller be an object that can route
        the request to the action-specific method.

        Examples:
          mapper = routes.Mapper()
          sc = ServerController()

          # Explicit mapping of one route to a controller+action
          mapper.connect(None, '/svrlist', controller=sc, action='list')

          # Actions are all implicitly defined
          mapper.resource('server', 'servers', controller=sc)

          # Pointing to an arbitrary WSGI app.  You can specify the
          # {path_info:.*} parameter so the target app can be handed just that
          # section of the URL.
          mapper.connect(None, '/v1.0/{path_info:.*}', controller=BlogApp())

        """
        self.map = mapper
        self._router = routes.middleware.RoutesMiddleware(self._dispatch,
                                                          self.map)

    @webob.dec.wsgify(RequestClass=Request)
    def __call__(self, req):
        """Route the incoming request to a controller based on self.map.

        If no match, return a 404.

        """
        return self._router

    @staticmethod
    @webob.dec.wsgify(RequestClass=Request)
    def _dispatch(req):
        """Dispatch the request to the appropriate controller.

        Called by self._router after matching the incoming request to a route
        and putting the information into req.environ.  Either returns 404
        or the routed WSGI app's response.

        """
        match = req.environ['wsgiorg.routing_args'][1]
        if not match:
            return webob.exc.HTTPNotFound()
        app = match['controller']
        return app

class Loader(object):
    """Used to load WSGI applications from paste configurations."""

    def __init__(self, config_path=None):
        """Initialize the loader, and attempt to find the config.

        :param config_path: Full or relative path to the paste config.
        :returns: None

        """
        config_path = config_path or FLAGS.api_paste_config
        self.config_path = utils.find_config(config_path)

    def load_app(self, name):
        """Return the paste URLMap wrapped WSGI application.

        :param name: Name of the application to load.
        :returns: Paste URLMap object wrapping the requested application.
        :raises: `nova.exception.PasteAppNotFound`

        """
        try:
            return deploy.loadapp("config:%s" % self.config_path, name=name)
        except LookupError as err:
            LOG.error(err)
            raise exception.PasteAppNotFound(name=name, path=self.config_path)


text:
package com.metamx.common;

/**
 */
public class IAE extends IllegalArgumentException
{
  public IAE(String formatText, Object... arguments)
  {
    super(String.format(formatText, arguments));
  }

  public IAE(Throwable cause, String formatText, Object... arguments)
  {
    super(String.format(formatText, arguments), cause);
  }
}