text:
// ==========================================================================
//                 SeqAn - The Library for Sequence Analysis
// ==========================================================================
// Copyright (c) 2006-2015, Knut Reinert, FU Berlin
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
//       its contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// ==========================================================================

#ifndef SEQAN_HEADER_GRAPH_IMPL_TREE_H
#define SEQAN_HEADER_GRAPH_IMPL_TREE_H

namespace SEQAN_NAMESPACE_MAIN
{
//////////////////////////////////////////////////////////////////////////////
// Graph - Tree
//////////////////////////////////////////////////////////////////////////////

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

/*!
 * @class Tree
 * @headerfile <seqan/graph_types.h>
 * @extends Graph
 * @brief A tree.
 *
 * A Tree has a distinct root and directed edges.  The source vertex of each edge is the parent vertex, the target
 * vertex of each edge is the child.  Trees provide fast access to child vertices and the parent.
 *
 * @signature template <[typename TCargo[, typename TSpec]]>
 *            class Graph<Tree<TCargo, TSpec> >;
 *
 * @tparam TCargo The cargo type that can be attached to the edges.  Default: <tt>void</tt>.
 * @tparam TSpec  Specializing type.  Default: <tt>Default</tt>.
 */

template<typename TCargo, typename TSpec>
class Graph<Tree<TCargo, TSpec> >
{
    public:
        typedef typename VertexIdHandler<Graph>::Type TVertexIdManager_;
        typedef typename VertexDescriptor<Graph>::Type TVertexDescriptor_;
        typedef typename EdgeType<Graph>::Type TEdgeStump_;
        typedef Allocator<SinglePool<sizeof(TEdgeStump_)> > TAllocator_;

        TVertexDescriptor_ data_root;
        String<TEdgeStump_*> data_vertex;            // Pointers to EdgeStumpT lists
        String<TVertexDescriptor_> data_parent;        // Map to the parents of each node
        TVertexIdManager_ data_id_managerV;
        TAllocator_ data_allocator;

//____________________________________________________________________________

        Graph() : data_root(getNil<TVertexDescriptor_>()) {
            SEQAN_CHECKPOINT
        }

        ~Graph() {
            SEQAN_CHECKPOINT
            clear(*this);
        }

        Graph(Graph const & _other) :
            data_root(getNil<TVertexDescriptor_>()),
            data_allocator(_other.data_allocator)
        {
            SEQAN_CHECKPOINT
            _copyGraph(_other, *this);
        }

        Graph const& operator = (Graph const & _other) {
            SEQAN_CHECKPOINT
            if (this == &_other) return *this;
            clear(*this);
            data_allocator = _other.data_allocator;
            _copyGraph(_other, *this);
            return *this;
        }
};

//////////////////////////////////////////////////////////////////////////////
// INTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////////////////////

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

template<typename TCargo, typename TSpec>
inline String<typename EdgeType<Graph<Tree<TCargo, TSpec> > >::Type*>&
_getVertexString(Graph<Tree<TCargo, TSpec> > const& g) {
    SEQAN_CHECKPOINT
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    return const_cast<String<TEdgeStump*>&>(g.data_vertex);
}

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

template<typename TCargo, typename TSpec>
inline IdManager<typename Id<Graph<Tree<TCargo, TSpec> > >::Type, Default> const &
_getVertexIdManager(Graph<Tree<TCargo, TSpec> > const& g) {
    return g.data_id_managerV;
}

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

template<typename TCargo, typename TSpec>
inline IdManager<typename Id<Graph<Tree<TCargo, TSpec> > >::Type, Default> &
_getVertexIdManager(Graph<Tree<TCargo, TSpec> >& g) {
    return g.data_id_managerV;
}

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

template<typename TCargo, typename TSpec>
inline IdManager<typename Id<Graph<Tree<TCargo, TSpec> > >::Type, Default> const &
_getEdgeIdManager(Graph<Tree<TCargo, TSpec> > const& g) {
    return g.data_id_managerV;
}

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

template<typename TCargo, typename TSpec>
inline IdManager<typename Id<Graph<Tree<TCargo, TSpec> > >::Type, Default> &
_getEdgeIdManager(Graph<Tree<TCargo, TSpec> >& g) {
    return g.data_id_managerV;
}

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

template<typename TCargo, typename TSpec>
inline void
_rebuildParentMap(Graph<Tree<TCargo, TSpec> >& g)
{
    SEQAN_CHECKPOINT

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename VertexDescriptor<TGraph>::Type TVertexDescriptor;
    typedef typename Iterator<String<TEdgeStump*>, Standard>::Type TIterConst;
    TIterConst it = begin(g.data_vertex, Standard());
    TIterConst itEnd = end(g.data_vertex, Standard());
    TVertexDescriptor pos = 0;
    for(;it!=itEnd; ++it, ++pos) {
        TVertexDescriptor parent = pos;
        TEdgeStump* current = *it;
        while(current!=0) {
            g.data_parent[getTarget(current)] = parent;
            current = getNextT(current);
        }
    }
}

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

template<typename TCargo, typename TSpec>
inline void
_copyGraph(Graph<Tree<TCargo, TSpec> > const& source,
           Graph<Tree<TCargo, TSpec> >& dest,
           bool transpose)
{
    SEQAN_CHECKPOINT
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename VertexDescriptor<TGraph>::Type TVertexDescriptor;
    typedef typename EdgeDescriptor<TGraph>::Type TEdgeDescriptor;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename Iterator<String<TEdgeStump*> const, Standard>::Type TIterConst;
    typedef typename Iterator<String<TEdgeStump*>, Standard>::Type TIter;
    clear(dest);
    resize(dest.data_vertex, length(source.data_vertex));
    resize(dest.data_parent, length(source.data_parent));
    TIter itInit = begin(dest.data_vertex, Standard());
    TIter itInitEnd = end(dest.data_vertex, Standard());
    for(;itInit != itInitEnd; ++itInit) *itInit = (TEdgeStump*) 0;
    TIterConst it = begin(source.data_vertex, Standard());
    TIterConst itEnd = end(source.data_vertex, Standard());
    TVertexDescriptor pos = 0;
    for(;it!=itEnd;++it, ++pos) {
        TEdgeStump* current = *it;
        TVertexDescriptor parentVertex = pos;
        while(current != (TEdgeStump*) 0) {
            TVertexDescriptor childVertex = getTarget(current);
            // Create missing vertices
            if (parentVertex > childVertex) _createVertices(dest,parentVertex);
            else _createVertices(dest,childVertex);
            // Add edge
            TEdgeDescriptor e;
            if (!transpose) e = addEdge(dest, parentVertex, childVertex);
            else e = addEdge(dest, childVertex, parentVertex);
            assignCargo(e, getCargo(current));
            current = getNextT(current);
        }
    }
    dest.data_id_managerV = source.data_id_managerV;
    dest.data_root = source.data_root;
}

template<typename TCargo, typename TSpec>
inline void
_copyGraph(Graph<Tree<TCargo, TSpec> > const& source,
           Graph<Tree<TCargo, TSpec> >& dest)
{
    _copyGraph(source, dest, false);
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
//////////////////////////////////////////////////////////////////////////////

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

template<typename TCargo, typename TSpec>
inline void
transpose(Graph<Tree<TCargo, TSpec> > const& source,
          Graph<Tree<TCargo, TSpec> >& dest)
{
    SEQAN_CHECKPOINT
    _copyGraph(source, dest, true);

}

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

template<typename TCargo, typename TSpec>
inline void
transpose(Graph<Tree<TCargo, TSpec> >& g)
{
    SEQAN_CHECKPOINT
    Graph<Tree<TCargo, TSpec> > dest;
    _copyGraph(g, dest, true);
    g = dest;
}

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

template<typename TCargo, typename TSpec>
inline typename Size<Graph<Tree<TCargo, TSpec> > >::Type
numEdges(Graph<Tree<TCargo, TSpec> > const& g)
{
    SEQAN_CHECKPOINT
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename Size<TGraph>::Type TSize;
    typedef typename Iterator<String<TEdgeStump*> const, Standard>::Type TIterConst;
    TSize count=0;
    TIterConst it = begin(g.data_vertex, Standard());
    TIterConst itEnd = end(g.data_vertex, Standard());
    for(;it!=itEnd;++it) {
        TEdgeStump* current = *it;
        while(current!=0) {
            ++count;
            current = getNextT(current);
        }
    }
    return count;
}

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

template<typename TCargo, typename TSpec>
inline typename Size<Graph<Tree<TCargo, TSpec> > >::Type
numVertices(Graph<Tree<TCargo, TSpec> > const& g)
{
    SEQAN_CHECKPOINT
    return idCount(g.data_id_managerV);
}

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

template<typename TCargo, typename TSpec>
inline bool
empty(Graph<Tree<TCargo, TSpec> > const& g)
{
    SEQAN_CHECKPOINT
    return (!idCount(g.data_id_managerV));
}

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

template<typename TCargo, typename TSpec>
inline void
clearEdges(Graph<Tree<TCargo, TSpec> >& g)
{
    SEQAN_CHECKPOINT

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename VertexDescriptor<TGraph>::Type TVertexDescriptor;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename Iterator<String<TEdgeStump*>, Standard>::Type TIter;
    TIter it = begin(g.data_vertex, Standard());
    TIter itEnd = end(g.data_vertex, Standard());
    TVertexDescriptor nilVertex = getNil<TVertexDescriptor>();
    TVertexDescriptor pos = 0;
    for(;it!=itEnd;++it, ++pos) {
        TEdgeStump* current = *it;
        if(current != (TEdgeStump*) 0) {
            g.data_parent[pos] = nilVertex;
            removeOutEdges(g, pos);
        }
    }
}

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

template<typename TCargo, typename TSpec>
inline void
clearVertices(Graph<Tree<TCargo, TSpec> >& g)
{
    SEQAN_CHECKPOINT
    clearEdges(g);
    releaseAll(g.data_id_managerV);
    clear(g.data_vertex);
    clear(g.data_parent);
}

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

template<typename TCargo, typename TSpec>
inline void
clear(Graph<Tree<TCargo, TSpec> >& g)
{
    SEQAN_CHECKPOINT
    clearVertices(g);
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename Size<Graph<Tree<TCargo, TSpec> > >::Type
outDegree(Graph<Tree<TCargo, TSpec> > const& g,
          TVertexDescriptor const vertex)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, vertex));

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename Size<TGraph>::Type TSize;
    TSize count=0;
    TEdgeStump* current = g.data_vertex[vertex];
    while(current!=0) {
        current = getNextT(current);
        ++count;
    }
    return count;
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename Size<Graph<Tree<TCargo, TSpec> > >::Type
inDegree(Graph<Tree<TCargo, TSpec> > const& g,
         TVertexDescriptor const vertex)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, vertex));

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename Size<TGraph>::Type TSize;
    typedef typename Iterator<String<TEdgeStump*> const, Standard>::Type TIterConst;
    TSize count=0;
    TIterConst it = begin(g.data_vertex, Standard());
    TIterConst itEnd = end(g.data_vertex, Standard());
    for(;it!=itEnd;++it) {
        TEdgeStump* current = *it;
        while(current!=0) {
            if ( (TVertexDescriptor) getTarget(current)==vertex) ++count;
            current = getNextT(current);
        }
    }
    return count;
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename Size<Graph<Tree<TCargo, TSpec> > >::Type
degree(Graph<Tree<TCargo, TSpec> > const& g,
       TVertexDescriptor const vertex)
{
    SEQAN_CHECKPOINT
    return (inDegree(g,vertex)+outDegree(g,vertex));
}

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

template<typename TCargo, typename TSpec>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
addVertex(Graph<Tree<TCargo, TSpec> >& g)
{
    SEQAN_CHECKPOINT
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename VertexDescriptor<TGraph>::Type TVertexDescriptor;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    TVertexDescriptor nilVertex = getNil<TVertexDescriptor>();
    TVertexDescriptor vd;
    if (empty(g)) g.data_root = vd = obtainId(g.data_id_managerV);
    else vd = obtainId(g.data_id_managerV);
    if (vd == length(g.data_vertex)) {
        appendValue(g.data_vertex, (TEdgeStump*) 0);
        resize(g.data_parent, vd + 1, nilVertex, Generous());
    } else {
        g.data_vertex[vd] = (TEdgeStump*) 0;
        g.data_parent[vd] = nilVertex;
    }
    return vd;
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline void
removeVertex(Graph<Tree<TCargo, TSpec> >& g,
             TVertexDescriptor const v)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, v));

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    TVertexDescriptor nilVertex = getNil<TVertexDescriptor>();
    TEdgeStump* current = getValue(g.data_vertex, v);
    while(current!=0) {
        g.data_parent[childVertex(g, current)] = nilVertex;
        current = getNextT(current);
    }
    g.data_parent[v] = nilVertex;
    removeOutEdges(g,v); // Remove all outgoing edges
    removeInEdges(g,v); // Remove all incoming edges
    releaseId(g.data_id_managerV, v); // Release id
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename EdgeDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
addEdge(Graph<Tree<TCargo, TSpec> >& g,
        TVertexDescriptor const parent,
        TVertexDescriptor const child)
{
    SEQAN_ASSERT(idInUse(g.data_id_managerV, parent));
    SEQAN_ASSERT(idInUse(g.data_id_managerV, child));
    SEQAN_ASSERT(findEdge(g, parent, child) == 0); // No multi-graphs as trees!!!

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;

    TEdgeStump* edge_ptr;
    allocate(g.data_allocator, edge_ptr, 1);
    valueConstruct(edge_ptr);
    assignTarget(edge_ptr, child);
    g.data_parent[child] = parent;
    assignNextT(edge_ptr, (TEdgeStump*) 0);
    if (g.data_vertex[parent]!=0) assignNextT(edge_ptr, g.data_vertex[parent]);
    g.data_vertex[parent]=edge_ptr;
    return edge_ptr;
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename EdgeDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
addEdge(Graph<Tree<TCargo, TSpec> >& g,
        TVertexDescriptor const parent,
        TVertexDescriptor const child,
        TCargo const cargo)
{
    SEQAN_CHECKPOINT
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeDescriptor<TGraph>::Type TEdgeDescriptor;
    TEdgeDescriptor e = addEdge(g,parent,child);
    assignCargo(e,cargo);
    return e;
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline void
removeEdge(Graph<Tree<TCargo, TSpec> >& g,
           TVertexDescriptor const parent,
           TVertexDescriptor const child)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, parent));
    SEQAN_ASSERT(idInUse(g.data_id_managerV, child));

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;

    // Find edge and predecessor
    TEdgeStump* pred = 0;
    TEdgeStump* current = g.data_vertex[parent];
    while(current != (TEdgeStump*) 0) {
        if ( (TVertexDescriptor) getTarget(current) == child) break;
        pred = current;
        current = getNextT(current);
    }

    // Not found?
    if (current == (TEdgeStump*) 0) return;
    g.data_parent[child] = getNil<TVertexDescriptor>();

    // Relink the next pointer of predecessor
    if (pred != (TEdgeStump*) 0) assignNextT(pred, getNextT(current));
    else g.data_vertex[parent] = getNextT(current);

    // Deallocate
    valueDestruct(current);
    deallocate(g.data_allocator, current, 1);
}

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

template<typename TCargo, typename TSpec, typename TEdgeDescriptor>
inline void
removeEdge(Graph<Tree<TCargo, TSpec> >& g,
           TEdgeDescriptor const edge)
{
    SEQAN_CHECKPOINT
    removeEdge(g, parentVertex(g,edge), childVertex(g,edge));
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline void
removeOutEdges(Graph<Tree<TCargo, TSpec> >& g,
               TVertexDescriptor const v)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, v));

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    while(g.data_vertex[v] != (TEdgeStump*) 0) {
        TVertexDescriptor target = targetVertex(g,g.data_vertex[v]);
        removeEdge(g,v,target);
    }
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline void
removeInEdges(Graph<Tree<TCargo, TSpec> >& g,
              TVertexDescriptor const v)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, v));

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename Iterator<String<TEdgeStump*>, Standard>::Type TIter;
    TIter it = begin(g.data_vertex, Standard());
    TIter itEnd = end(g.data_vertex, Standard());
    TVertexDescriptor pos = 0;
    for(;it!=itEnd;++it, ++pos) {
        if (!idInUse(g.data_id_managerV, pos)) continue;
        TEdgeStump* current = *it;
        TVertexDescriptor const sourceVertex = pos;
        while(current!=0) {
            if ( (TVertexDescriptor) current->data_target==v) {
                removeEdge(g, sourceVertex, v);
                current = g.data_vertex[sourceVertex];
            } else {
                current = getNextT(current);
            }
        }
    }
}

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

template<typename TCargo, typename TSpec, typename TEdgeDescriptor>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
targetVertex(Graph<Tree<TCargo, TSpec> > const&,
             TEdgeDescriptor const edge)
{
    SEQAN_CHECKPOINT
    return getTarget(edge);
}

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

template<typename TCargo, typename TSpec, typename TEdgeDescriptor>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
sourceVertex(Graph<Tree<TCargo, TSpec> > const& g,
             TEdgeDescriptor const edge)
{
    SEQAN_CHECKPOINT
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename VertexDescriptor<TGraph>::Type TVertexDescriptor;
    typedef typename Iterator<String<TEdgeStump*> const, Standard>::Type TIterConst;
    TIterConst it = begin(g.data_vertex, Standard());
    TIterConst itEnd = end(g.data_vertex, Standard());
    TVertexDescriptor pos = 0;
    for(;it!=itEnd;++it, ++pos) {
        TEdgeDescriptor current = *it;
        while(current!=(TEdgeDescriptor) 0) {
            if (current == edge) return pos;
            current=getNextT(current);
        }
    }
    return 0;
}

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

template<typename TCargo, typename TSpec, typename TMatrix>
inline void
getAdjacencyMatrix(Graph<Tree<TCargo, TSpec> > const& g,
                   TMatrix& mat)
{
    SEQAN_CHECKPOINT
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename VertexDescriptor<TGraph>::Type TVertexDescriptor;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename Size<TMatrix>::Type TSize;
    TSize len = getIdUpperBound(g.data_id_managerV);
    resize(mat, len*len, 0);

    typedef typename Iterator<String<TEdgeStump*> const, Standard>::Type TIterConst;
    TIterConst it = begin(g.data_vertex, Standard());
    TIterConst itEnd = end(g.data_vertex, Standard());
    TVertexDescriptor pos = 0;
    for(;it!=itEnd;++it,++pos) {
        TVertexDescriptor parentV = pos;
        TEdgeStump* current = *it;
        while(current!=0) {
            TVertexDescriptor childV = getTarget(current);
            ++mat[parentV*len+childV];
            current=getNextT(current);
        }
    }
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename EdgeDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
findEdge(Graph<Tree<TCargo, TSpec> >& g,
         TVertexDescriptor const v,
         TVertexDescriptor const w)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, v));
    SEQAN_ASSERT(idInUse(g.data_id_managerV, w));

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;

    if ((TVertexDescriptor)g.data_parent[w] == v) {
        TEdgeStump* current = g.data_vertex[v];
        while((TEdgeStump*) current != 0) {
            if ((TVertexDescriptor) getTarget(current) == w) return current;
            current = getNextT(current);
        }
    } else if ((TVertexDescriptor) g.data_parent[v] == w) {
        TEdgeStump* current = g.data_vertex[w];
        while((TEdgeStump*) current != 0) {
            if ((TVertexDescriptor) getTarget(current) == v) return current;
            current = getNextT(current);
        }
    }
    return 0;
}

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

template <typename TFile, typename TCargo, typename TSpec>
inline void
write(TFile & target,
      Graph<Tree<TCargo, TSpec> > const& g)
{
//IOREV _nodoc_
    SEQAN_CHECKPOINT
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    typedef typename VertexDescriptor<TGraph>::Type TVertexDescriptor;
    typedef typename Iterator<String<TEdgeStump*> const, Standard>::Type TIterConst;
    TIterConst it = begin(g.data_vertex, Standard());
    TIterConst itEnd = end(g.data_vertex, Standard());
    TVertexDescriptor pos = 0;
    write(target, "Adjacency list:\n");
    for(;it!=itEnd;++it, ++pos) {
        if (!idInUse(_getVertexIdManager(g),pos)) continue;
        TEdgeStump* current = *it;
        appendNumber(target, (int)pos);
        write(target, " -> ");
        while(current!=0) {
            appendNumber(target, (int)getTarget(current));
            writeValue(target, ',');
            current=getNextT(current);
        }
        writeValue(target, '\n');
    }
    it = begin(g.data_vertex, Standard());
    pos = 0;
    write(target, "Edge list:\n");
    for(;it!=itEnd;++it, ++pos) {
        TEdgeStump* current = getValue(it);
        while(current!=0) {
            write(target, "Source: ");
            appendNumber(target, (int)pos);
            writeValue(target, ',');
            write(target, "Target: ");
            appendNumber(target, (int)getTarget(current));
            writeValue(target, ' ');
            write(target, "(Id: ");
            appendNumber(target, (int)_getId(current));
            writeValue(target, ')');
            writeValue(target, '\n');
            current=getNextT(current);
        }
    }
}

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

/*!
 * @fn Tree#assignRoot
 * @brief Assign a new root vertex to the tree.
 *
 * @signature void assignRoot(t, v);
 *
 * @param[in,out] t The Tree to assign the root for.
 * @param[in]     v A vertex descriptor.
 */

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline void
assignRoot(Graph<Tree<TCargo, TSpec> >& g,
           TVertexDescriptor const vertex)
{
    SEQAN_ASSERT(idInUse(g.data_id_managerV, vertex));

    g.data_root = vertex;
    g.data_parent[vertex] = getNil<TVertexDescriptor>();
}

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

/*!
 * @fn Tree#createRoot
 * @brief Creates the root for the tree.
 *
 * @signature void createRoot(t);
 *
 * @param[in,out] t The Tree to create the root for.
 */

template<typename TCargo, typename TSpec>
inline void
createRoot(Graph<Tree<TCargo, TSpec> >& g)
{
    SEQAN_CHECKPOINT
    g.data_root = addVertex(g);
}

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

/*!
 * @fn Tree#root
 * @brief Gets reference to the root of the tree.
 *
 * @signature TVertexDescriptor root(t);
 *
 * @param[in] t The Tree to query for its root.
 *
 * @return TVertexDescriptor Reference to the root's vertex descriptor.
 */

template<typename TCargo, typename TSpec>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type&
root(Graph<Tree<TCargo, TSpec> >& g)
{
    SEQAN_CHECKPOINT
    return g.data_root;
}

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

/*!
 * @fn Tree#getRoot
 * @brief Gets the root of the tree.
 *
 * @signature TVertexDescriptor getRoot(t);
 *
 * @param[in] t The Tree to query for its root.
 *
 * @return TVertexDescriptor The root's vertex descriptor.
 */

template<typename TCargo, typename TSpec>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
getRoot(Graph<Tree<TCargo, TSpec> > const& g)
{
    SEQAN_CHECKPOINT
    return g.data_root;
}

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

/*!
 * @fn Tree#isRoot
 * @brief Tests whether a given vertex is the root or not.
 *
 * @signature bool isRoot(t, v);
 *
 * @param[in] a The Tree to query.
 * @param[in] t The descriptor of the vertex to query.
 *
 * @return bool true if v is the root and false otherwise.
 */

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline bool
isRoot(Graph<Tree<TCargo, TSpec> > const& g,
       TVertexDescriptor v)
{
    SEQAN_CHECKPOINT
    return ( (TVertexDescriptor) g.data_root == v);
}

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

/*!
 * @fn Tree#isLeaf
 * @brief Tests whether a given vertex is a leaf or not.
 *
 * @signature bool isLeaf(g, v);
 *
 * @param[in] g The Tree to query.
 * @param[in] v The descriptor of the vertex to query for.
 */

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline bool
isLeaf(Graph<Tree<TCargo, TSpec> > const& g,
       TVertexDescriptor v)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, v));

    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;
    return (g.data_vertex[v] ==  (TEdgeStump*) 0);
}

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

/*!
 * @fn Tree#numTreeEdges
 * @brief Number of tree edges.
 *
 * @signature TSize numTreeEdges(g);
 *
 * @param[in] g The tree to query.
 *
 * @return TSize The number of tree edges.  Faster than @link Graph#numEdges @endlink for trees.
 */

template<typename TCargo, typename TSpec>
inline typename Size<Graph<Tree<TCargo, TSpec> > >::Type
numTreeEdges(Graph<Tree<TCargo, TSpec> > const& g)
{
    SEQAN_CHECKPOINT
    if (empty(g)) return 0;
    else return numVertices(g) - 1;
}

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

/*!
 * @fn Tree#numChildren
 * @brief Number of children of a given tree vertex.
 *
 * @signature TSize numChildren(g, v);
 *
 * @param[in] g The Tree to query.
 * @param[in] v The descriptor of the vertex to count the children of.
 *
 * @return TSize The number of children.
 */

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename Size<Graph<Tree<TCargo, TSpec> > >::Type
numChildren(Graph<Tree<TCargo, TSpec> > const& g,
            TVertexDescriptor const vertex)
{
    SEQAN_CHECKPOINT

    return outDegree(g, vertex);
}

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

/*!
 * @fn Tree#addChild
 * @brief Adds a new child vertex to a parent vertex, optionally with an edge cargo.
 *
 * @signature TVertexDescriptor(g, parent[, cargo]);
 *
 * @param[in,out] g      The Tree to append the vertex and edge to.
 * @param[in]     parent Descriptor of the parent vertex.
 * @param[in]     cargo  The cargo to attach to the edge.
 *
 * @return TVertexDescriptor Vertex descriptor of the added vertex.
 */

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
addChild(Graph<Tree<TCargo, TSpec> >& g,
         TVertexDescriptor parent)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, parent));
    TVertexDescriptor child = addVertex(g);
    addEdge(g,parent,child);
    return child;
}

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

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
addChild(Graph<Tree<TCargo, TSpec> >& g,
         TVertexDescriptor const parent,
         TCargo const cargo)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, parent));
    TVertexDescriptor child = addVertex(g);
    addEdge(g,parent,child,cargo);
    return child;
}

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

/*!
 * @fn Tree#removeChild
 * @brief Removes a child from the tree given a parent.
 *
 * @signature void removeChidl(g, parent, child);
 *
 * @param[in,out] g      The Tree to remove the vertex from.
 * @param[in]     parent The descriptor of the parent vertex.
 * @param[in]     child  The descriptor of the child vertex.
 */

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline void
removeChild(Graph<Tree<TCargo, TSpec> >& g,
            TVertexDescriptor const parent,
            TVertexDescriptor const child)
{
    SEQAN_CHECKPOINT
    if (!isLeaf(g,child)) removeAllChildren(g,child);
    removeEdge(g,parent, child);  // Parent map is cleared in removeEdge
    releaseId(g.data_id_managerV, child); // Release id
}

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

/*!
 * @fn Tree#removeAllChildren
 * @brief Removes all children from the tree given a parent.
 *
 * @signature void removeAllChildren(g, parent);
 *
 * @param[in,out] g      The Tree to modify.
 * @param[in]     parent Descriptor of the vertex to remove children of.
 */

template<typename TCargo, typename TSpec, typename TVertexDescriptor>
inline void
removeAllChildren(Graph<Tree<TCargo, TSpec> >& g,
                  TVertexDescriptor const parent)
{
    SEQAN_CHECKPOINT
    SEQAN_ASSERT(idInUse(g.data_id_managerV, parent));
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename EdgeType<TGraph>::Type TEdgeStump;

    while(g.data_vertex[parent] != (TEdgeStump*) 0) {
        TVertexDescriptor child = childVertex(g,g.data_vertex[parent]);
        if (!isLeaf(g,child)) removeAllChildren(g,child);
        removeEdge(g,parent, child);  // Parent map is cleared in removeEdge
        releaseId(g.data_id_managerV, child); // Release id
    }
}

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

/*!
 * @fn Tree#childVertex
 * @brief Returns the child vertex of an edge.
 *
 * @signature TVertexDescriptor childVertex(g, e);
 *
 * @param[in] g The Tree to query.
 * @param[in] e The edge descriptor of the edge to query.
 *
 * @return TVertexDescriptor The descriptor of the child vertex.
 */

template<typename TCargo, typename TSpec, typename TEdgeDescriptor>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
childVertex(Graph<Tree<TCargo, TSpec> > const&,
            TEdgeDescriptor const edge)
{
    SEQAN_CHECKPOINT
    return getTarget(edge);
}

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

/*!
 * @fn Tree#parentVertex
 * @brief Returns the parent vertex of an edge.
 *
 * @signature TVertexDescriptor childVertex(g, e);
 * @signature TVertexDescriptor childVertex(g, v);
 *
 * @param[in] g The Tree to query.
 * @param[in] e The edge descriptor of the edge to query.
 * @param[in] v The descriptor of the vertex to query.
 *
 * @return TVertexDescriptor The descriptor of the child vertex.
 */

template<typename TCargo, typename TSpec>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
parentVertex(Graph<Tree<TCargo, TSpec> > const& g,
             typename EdgeDescriptor<Graph<Tree<TCargo, TSpec> > >::Type const edge)
{
    SEQAN_CHECKPOINT
    return g.data_parent[getTarget(edge)];
}

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

template<typename TCargo, typename TSpec>
inline typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type
parentVertex(Graph<Tree<TCargo, TSpec> > const& g,
             typename VertexDescriptor<Graph<Tree<TCargo, TSpec> > >::Type const v)
{
    SEQAN_CHECKPOINT
    return g.data_parent[v];
}

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

/*!
 * @fn Tree#collectLeaves
 * @brief Returns all leaves underneath a given vertex.
 *
 * @signature void collectLeaves(g, v, group);
 *
 * @param[in]  g     The Tree to collect the leaves for.
 * @param[in]  v     The root of the subtree to query the leaves of.
 * @param[out] group A @link String @endlink of leaf vertex descriptors.
 */

template<typename TCargo, typename TSpec, typename TVertexDescriptor, typename TGroup>
inline void
collectLeaves(Graph<Tree<TCargo, TSpec> > const& g,
              TVertexDescriptor const root,
              TGroup& group)
{
    typedef Graph<Tree<TCargo, TSpec> > TGraph;
    typedef typename Iterator<TGraph, AdjacencyIterator>::Type TAdjacencyIterator;

    if (isLeaf(g, root)) appendValue(group, root, Generous());
    else {
        TAdjacencyIterator adjIt(g, root);
        for(;!atEnd(adjIt);goNext(adjIt)) {
            collectLeaves(g, *adjIt, group);
        }
    }
}

}// namespace SEQAN_NAMESPACE_MAIN

#endif //#ifndef SEQAN_HEADER_...


text:
namespace chromecast {

// Chromecast implementation of blink::WebContentSettingsClient.
class CastContentSettingsClient : public content::RenderFrameObserver,
                                  public blink::WebContentSettingsClient {
 public:
  CastContentSettingsClient(content::RenderFrame* render_view,
                            const std::string& app_id,
                            bool allow_insecure_content);
  CastContentSettingsClient(const CastContentSettingsClient&) = delete;
  CastContentSettingsClient& operator=(const CastContentSettingsClient&) =
      delete;

 private:
  ~CastContentSettingsClient() override;

  // content::RenderFrameObserver implementation.
  void OnDestruct() override;

  // blink::WebContentSettingsClient implementation.
  bool AllowRunningInsecureContent(bool enabled_per_settings,
                                   const blink::WebURL& url) override;
  void PassiveInsecureContentFound(const blink::WebURL&) override;
  bool ShouldAutoupgradeMixedContent() override;

  void ReportRendererFeatureUse(const std::string& app_id,
                                const std::string& feature_name);

  const std::string app_id_;
  const bool allow_insecure_content_;
  // TODO(b/150022618): Add decisions from Cast service to control the
  // availibilitiy of the Renderer features.

  mojo::Remote<metrics::mojom::MetricsHelper> metrics_helper_remote_;
};

}  // namespace chromecast

#endif  // CHROMECAST_RENDERER_CAST_CONTENT_SETTINGS_CLIENT_H_

redpajama_set_name: RedPajamaGithub


text:
require 'helpers/import'
import 'helpers/path'
import 'yuzu/core/website_folder'

Dir.glob(File.join(File.dirname(__FILE__), "..", "generators", "*")).each do |c|
  import c
end

module Yuzu::Core
  class SiteRoot < WebsiteFolder
    include Yuzu::Generators

    attr_reader :config
    def initialize(yuzu_config, path=nil)
      @config = yuzu_config
      @path = path.nil? ? Path.pwd : Path.new(path)
      @parent = nil
      @kind = :folder

      generate!
    end

    def name
      @config.site_name
    end

    # Given a Path, return the WebsiteFile or WebsiteFolder corresponding to the Path.
    def find_file_by_path(path)
      path_elements = path.relative.split(File::SEPARATOR)

      parent = self
      path_elements.each do |element|
        child = parent.get_child_by_rootname(element)
        return nil if child.nil?
        parent = child
      end

      return parent
    end

    def generators
      Generator.generators
    end

    # Process all the generators to make all the new files required from things like pagination of
    # catalogs and new index files.
    def generate!
      generators.each_pair do |name, generator|
        v = Visitor.new(generator.visitor_filter)

        v.traverse(self) do |node|
          if generator.should_generate?(node)
            generator.generate!(node)
          end
        end
      end
    end
  end

end


text:
    <edit-user-form></edit-user-form>

Users list
            <button type="button" data-toggle="modal" data-target="#editUserModal"
                    class="btn btn-success" ng-click="newUser()">

            </button>

                    #
                    Name
                    Username
                    Email
                    Role

                    {{user.id}}
                    {{user.name}}
                    {{user.username}}
                    {{user.email}}
                    {{user.role}}

                        <button type="button" ng-click="editUser(user)"
                                data-toggle="modal" data-target="#editUserModal" class="btn btn-warning">

                        </button>

                        <button type="button" ng-click="deleteUser(user)" class="btn btn-danger">

                        </button>


text:
class Ability
  include CanCan::Ability

  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
    #   user ||= User.new # guest user (not logged in)
    #   if user.admin?
    #     can :manage, :all
    #   else
    #     can :read, :all
    #   end
    #
    # The first argument to `can` is the action you are giving the user
    # permission to do.
    # If you pass :manage it will apply to every action. Other common actions
    # here are :read, :create, :update and :destroy.
    #
    # The second argument is the resource the user can perform the action on.
    # If you pass :all it will apply to every resource. Otherwise pass a Ruby
    # class of the resource.
    #
    # The third argument is an optional hash of conditions to further filter the
    # objects.
    # For example, here the user can only update published articles.
    #
    #   can :update, Article, :published => true
    #
    # See the wiki for details:
    # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
    alias_action :create, :read, :update, :destroy, to: :crud

    if user.present?
      if user.admin?
        can :manage, :all
      elsif user.contributor?
        can %i[update create], Broadcast
      end

      can :crud, Impression, user_id: user.id
      can %i[read update], User, id: user.id
    end

    # defaults for any user
    can :read, Broadcast
    can :read, Format
    can :read, Topic
    can :read, Medium
    can :read, Station
    can :summarized, Statistic
    can :read, Statistic::Medium
    can :read, Statistic::Station
    can %i[read temporal history], Statistic::Broadcast
  end
end


text:
from __future__ import absolute_import, division, print_function

from .light import LightComponent
from .material import MaterialComponent
from .render import RenderComponent


text:
import sys
sys.path.append("../common/tests")
from test_utils import *
import test_common

class ApiServerTestCase(test_common.TestCase):
    def setUp(self):
        super(ApiServerTestCase, self).setUp()
        self.ignore_err_in_log = False

    def tearDown(self):
        try:
            if self.ignore_err_in_log:
                return

            with open('api_server_%s.log' %(self.id())) as f:
                lines = f.read()
                self.assertIsNone(
                    re.search('SYS_ERR', lines), 'Error in log file')
        except IOError:
            # vnc_openstack.err not created, No errors.
            pass
        finally:
            super(ApiServerTestCase, self).tearDown()
# end class ApiServerTestCase


text:
package test

import (
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/open-policy-agent/frameworks/constraint/pkg/types"
	"github.com/open-policy-agent/gatekeeper/pkg/gator/test"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

// Test_formatOutput makes sure that the formatted output of `gator test`
// is consitent as we iterate over the tool. The purpose of this test IS NOT
// testing the `gator test` results themselves.
func Test_formatOutput(t *testing.T) {
	constraintObj := &unstructured.Unstructured{}
	constraintObj.SetKind("kind")

	fooRes := types.Result{
		Target:     "foo",
		Constraint: constraintObj,
	}
	barObject := &unstructured.Unstructured{
		Object: map[string]interface{}{
			"bar": "xyz",
		},
	}
	xyzTrace := "xyz"

	testCases := []struct {
		name           string
		inputFormat    string
		input          []*test.GatorResult
		expectedOutput string
	}{
		{
			name: "default output",
			// inputFormat: "default", // note that the inputFormat defaults to "default"
			input: []*test.GatorResult{{
				Result:          fooRes,
				ViolatingObject: barObject,
				Trace:           nil,
			}},
			expectedOutput: `[""] Message: ""
`,
		},
		{
			name:        "yaml output",
			inputFormat: "YaML",
			input: []*test.GatorResult{{
				Result:          fooRes,
				ViolatingObject: barObject,
				Trace:           &xyzTrace,
			}},
			expectedOutput: `- result:
    target: foo
    msg: ""
    metadata: {}
    constraint:
        object:
            kind: kind
    enforcementaction: ""
  violatingObject:
    bar: xyz
  trace: xyz
`,
		},
		{
			name:        "json output",
			inputFormat: "jSOn",
			input: []*test.GatorResult{{
				Result:          fooRes,
				ViolatingObject: barObject,
				Trace:           &xyzTrace,
			}},
			expectedOutput: `[
    {
        "target": "foo",
        "constraint": {
            "kind": "kind"
        },
        "violatingObject": {
            "bar": "xyz"
        },
        "trace": "xyz"
    }
]`,
		},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			output := formatOutput(tc.inputFormat, tc.input)
			if diff := cmp.Diff(tc.expectedOutput, output); diff != "" {
				t.Fatal(diff)
			}
		})
	}
}


text:
/*
	CCalDAVMultigetReport.h

	Author:
	Description:	<describe the CCalDAVMultigetReport class here>
*/

#ifndef CCalDAVMultigetReport_H
#define CCalDAVMultigetReport_H

#include "CWebDAVReport.h"

using namespace http;
using namespace webdav;

namespace http {

namespace caldav {

class CCalDAVMultigetReport: public CWebDAVReport
{
public:
	CCalDAVMultigetReport(CWebDAVSession* session, const cdstring& ruri, const cdstrvect& hrefs, bool old_style = false);
	virtual ~CCalDAVMultigetReport();

protected:
	bool	mOldStyle;

	void	InitRequestData(const cdstrvect& hrefs);

	void	GenerateXML(std::ostream& os, const cdstrvect& hrefs);
};

}	// namespace caldav

}	// namespace http

#endif	// CCalDAVMultigetReport_H


text:
module Ingress
  class Mission < ActiveRecord::Base
    include Import::Mission

    attr_accessor :from_csv_import
    attr_accessor :trace_urls
    attr_accessor :updating_range

    before_validation :initial_target_validation_level, on: :create
    after_create :populate_from_trace_urls
    after_save :update_range

    belongs_to :community,      inverse_of: :missions
    belongs_to :agent,          inverse_of: :missions
    belongs_to :mission_series, inverse_of: :missions

    has_many :mission_points, inverse_of: :mission

    has_many :points, through: :mission_points, inverse_of: :missions

    validates :name,                     presence: true
    validates :agent_id,                 presence: true
    validates :mission_url,              presence: true, uniqueness: true
    validates :sequence_type,            presence: true, if: :validation_level_two
    validates :series_type,              presence: true, if: :validation_level_two
    validates :difficulty_type,          presence: true, if: :validation_level_three
    validates :field_trip_waypoint_type, presence: true, if: :validation_level_three
    validates :field_trip_waypoint_qty,  presence: true, if: :validation_level_three
    validates :passphrase_type,          presence: true, if: :validation_level_three
    validates :validation_level,         inclusion: { in: 1..4 }

    enum sequence_type: {
      sequence_type_sequential:        1,
      sequence_type_sequential_hidden: 2,
      sequence_type_any_order:         3
    }

    enum series_type: {
      series_type_solo:     1,
      series_type_sequence: 2,
      series_type_banner:   3
    }

    # TODO: Do we wish to redo as bitmask, reassigning 17/18 manually?
    enum difficulty_type: {
      difficulty_type_not_set:             0,
      difficulty_type_all_hacks:           1,
      difficulty_type_all_capture_upgrade: 2,
      difficulty_type_all_modding:         4,
      difficulty_type_all_linking:         8,
      difficulty_type_all_fielding:        16,
      difficulty_type_easy:                17,
      difficulty_type_hard:                18
    }

    enum passphrase_type: {
      passphrase_type_not_set:  0,
      passphrase_type_none:     1,
      passphrase_type_logical:  2,
      passphrase_type_research: 3,
      passphrase_type_other:    4
    }

    enum field_trip_waypoint_type: {
      field_trip_waypoint_type_not_set: 0,
      field_trip_waypoint_type_none:    1,
      field_trip_waypoint_type_close:   2,
      field_trip_waypoint_type_medium:  3,
      field_trip_waypoint_type_far:     4
    }

    def populate_from_trace_urls
      return unless trace_urls.present?

      links = trace_urls.split("\n")
      links.each do |link|
        params = link.gsub('https://www.ingress.com/intel?', '').split('&')
        coords = params.detect { |param| /pls=/.match(param) }.gsub('pls=', '').split(/[,_]/)

        coords.each_slice(2) do |lat, long|
          point = Ingress::Point.where(lat: lat, long: long).first_or_create!

          Ingress::MissionPoint.create!(mission: self, point: point)

        end
      end

      self.trace_urls = nil
    end

    def as_json(options = {})
      super(options.merge(include: [:mission_series, :agent, :points]))
    end

    def update_range
      return if updating_range

      points.each do |point|
        if self.min_lat.nil?
          self.min_lat = point.lat
          self.max_lat = point.lat
          self.min_long = point.long
          self.max_long = point.long
        else
          self.min_lat  = [self.min_lat, point.lat].min unless point.lat.nil?
          self.max_lat  = [self.max_lat, point.lat].max unless point.lat.nil?
          self.min_long = [self.min_long, point.long].min unless point.long.nil?
          self.max_long = [self.max_long, point.long].max unless point.long.nil?
        end
      end

      self.updating_range = true

      save!
      # Save
      mission_series.try(:update_range)
    end

    private

    def initial_target_validation_level
      self.validation_level = 0
      return unless [name, agent, mission_url].all?(&:present?)
      self.validation_level = 1
      return unless [sequence_type, series_type].all?(&:present?)
      self.validation_level = 2
      return unless [difficulty_type, field_trip_waypoint_type, passphrase_type].all?(&:present?)
      self.validation_level = 3
      return unless [trace_urls, mission_points].any?(&:present?)
      self.validation_level = 4
    end

    def validation_level_one
      validation_level >= 1
    end

    def validation_level_two
      validation_level >= 2
    end

    def validation_level_three
      validation_level >= 3
    end

    def validation_level_four
      validation_level >= 4
    end
  end
end


text:
package org.fest.assertions.api;

import static junit.framework.Assert.assertSame;
import static org.fest.assertions.test.TestData.matchAnything;

import org.fest.assertions.internal.Strings;
import org.junit.*;

/**
 * Tests for <code>{@link StringAssert#matches(String)}</code>.
 *
 * @author Alex Ruiz
 */
public class StringAssert_matches_String_Test {

  private static String regex;

  private Strings strings;
  private StringAssert assertions;

  @BeforeClass public static void setUpOnce() {
    regex = matchAnything().pattern();
  }

  @Before public void setUp() {
    assertions = new StringAssert("Yoda");
    assertions.strings = strings;
  }

  @Test public void should_return_this() {
    StringAssert returned = assertions.matches(regex);
    assertSame(assertions, returned);
  }
}


text:
package br.ufsc.ftsm;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.Ordering;

import br.ufsc.core.trajectory.SemanticTrajectory;
import br.ufsc.core.trajectory.Trajectory;
import br.ufsc.db.source.DataRetriever;
import br.ufsc.db.source.DataSource;
import br.ufsc.db.source.DataSourceType;
import br.ufsc.ftsm.base.TrajectorySimilarityCalculator;
import br.ufsc.ftsm.related.UMS;
import br.ufsc.lehmann.msm.artigo.problems.BasicSemantic;
import br.ufsc.lehmann.msm.artigo.problems.SanFranciscoCabDatabaseReader;

public class TopK {

//	private static DataSource source;
//	private static DataRetriever retriever;

	public static void main(String[] args)
			throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
//		source = new DataSource("postgres", "postgis", "localhost", 5432, "postgis", DataSourceType.PGSQL, "crawdad",
//				null, "geom");
//		retriever = source.getRetriever();

//		testMethod("DTW",new DTWDistanceCalculator(), createTaxicabGroundtruth1TSToAirportDeparture(),T);
//		testMethod("DTW",new DTWDistanceCalculator(), createTaxicabGroundtruth2TSToUS(),T);
//		testMethod("DTW",new DTWDistanceCalculator(), createTaxicabGroundtruth3USToAirport(),T);
//		testMethod("DTW",new DTWDistanceCalculator(), createTaxicabGroundtruth4TSToAirportArrival(),T);
//		testMethod("DTW",new DTWDistanceCalculator(), createTaxicabGroundtruth5AirportArrivalToUS(),T);
//		testMethod("DTW",new DTWDistanceCalculator(), createTaxicabGroundtruth6TSToP39(),T);
//		testMethod("DTW",new DTWDistanceCalculator(), createTaxicabGroundtruth7USToP39(),T);

//		testMethod("UMSOnlyAlikeness3Pt",new UMSOnlyAlikeness3Pt(), createTaxicabGroundtruth1TSToAirportDeparture(),T);
//		testMethod("UMSOnlyAlikeness3Pt",new UMSOnlyAlikeness3Pt(), createTaxicabGroundtruth2TSToUS(),T);
//		testMethod("UMSOnlyAlikeness3Pt",new UMSOnlyAlikeness3Pt(), createTaxicabGroundtruth3USToAirport(),T);
//		testMethod("UMSOnlyAlikeness3Pt",new UMSOnlyAlikeness3Pt(), createTaxicabGroundtruth4TSToAirportArrival(),T);
//		testMethod("UMSOnlyAlikeness3Pt",new UMSOnlyAlikeness3Pt(), createTaxicabGroundtruth5AirportArrivalToUS(),T);
//		testMethod("UMSOnlyAlikeness3Pt",new UMSOnlyAlikeness3Pt(), createTaxicabGroundtruth6TSToP39(),T);
//		testMethod("UMSOnlyAlikeness3Pt",new UMSOnlyAlikeness3Pt(), createTaxicabGroundtruth7USToP39(),T);

//		testMethod("DTW",new DTWDistanceCalculator(), createTaxicabGroundtruth8P39ToTS(),T);
//		testMethod("UMSOA3",new UMSOnlyAlikeness3Pt(), createTaxicabGroundtruth8P39ToTS(),T);
//		testMethod("UMSNSF",new UMSNewSharenessFixed(), createTaxicabGroundtruth8P39ToTS(),T);
//
//		retriever.prepareFetchTrajectoryStatement();
//	testMethod("DTW",new DTWDistanceCalculator(), createGeolife1to6(),T);
//	testMethod("SDTW",new SDTW(), createGeolife1to6(),T);
		// testMethod("UMS",new UMSMathSimple(), createTaxicabGroundtruth6TSToP39(),T);
//	testMethod("UMS",new UMS(), GT.CD1.getTrajectories(),T);
//	testMethod("UMS",new UMSSpeed(), GT.CD1.getTrajectories(),T);

		String stopsTable = "stops_moves.sanfrancisco_taxicab_airport_mall_pier_park_fisherman_stop";
		String movesTable = "stops_moves.sanfrancisco_taxicab_airport_mall_pier_park_fisherman_move";
		String pointsTable = "taxi.sanfrancisco_taxicab_airport_mall_pier_park_fisherman_cleaned";
		List<SemanticTrajectory> T = new SanFranciscoCabDatabaseReader(false, null, null, null, stopsTable, movesTable, pointsTable).read();
		Multimap<String, SemanticTrajectory> Gs = MultimapBuilder.hashKeys().arrayListValues().build();
		BasicSemantic<String> groundtruth = new BasicSemantic<>(SanFranciscoCabDatabaseReader.ROADS_WITH_DIRECTION.getIndex());
		T.stream().forEach(t -> {
			Gs.put(groundtruth.getData(t, 0), t);
		});
		Gs.asMap().entrySet().stream().forEach(e -> {
			if(e.getKey() != null) {
				System.out.println(e.getKey());
				testMethod("UMS", new UMS(), new ArrayList<SemanticTrajectory>(e.getValue()), T);
			}
		});

//		testMethod("UMS Speed",new UMSSpeed(),GT.CD5.getTrajectories(),T);

//		testMethod("UMS",new UMS(), GT.CD6.getTrajectories(),T);
//		testMethod("UMS Speed",new UMSSpeed(),GT.CD6.getTrajectories(),T);
//
//		testMethod("UMS",new UMS(), GT.CD7.getTrajectories(),T);
//		testMethod("UMS Speed",new UMSSpeed(), GT.CD7.getTrajectories(),T);
//
//		testMethod("UMS",new UMS(), GT.CD2.getTrajectories(),T);
//		testMethod("UMS Speed",new UMSSpeed(),GT.CD2.getTrajectories(),T);
//
//		testMethod("UMS",new UMS(), GT.CD3.getTrajectories(),T);
//		testMethod("UMS Speed",new UMSSpeed(),GT.CD3.getTrajectories(),T);
//
//		testMethod("UMS",new UMS(), GT.CD4.getTrajectories(),T);
//		testMethod("UMS Speed",new UMSSpeed(), GT.CD4.getTrajectories(),T);
//
//
//	testMethod("UMS",new UMSSamsung(), GT.CD1.getTrajectories(),T);
//	testMethod("EDwP",new EditDistance(), GT.CD1.getTrajectories(),T);

	}

	private static void testMethod(String name, TrajectorySimilarityCalculator<SemanticTrajectory> tdc, List<SemanticTrajectory> G,
			List<SemanticTrajectory> T) {
		List<List<Double>> precisionAll = new ArrayList<List<Double>>();
		System.out.println("############### Method: " + name + " GT: " + G.size());
		long start = System.currentTimeMillis();
		int k = 0;
		for (SemanticTrajectory t1 : G) {
			// CircleTrajectory e = CreateCircle.createEllipticalTrajectory(t1);
			// ETrajectory e = CreateEllipseJTS.createEllipticalTrajectory(t1);
			List<Score> scoreList = new ArrayList<Score>();
			System.out.print(k + " ");
			k++;
			for (SemanticTrajectory t2 : T) {
				// Trajectory t2 = retriever.fastFetchTrajectory(tid2);
				// ETrajectory e2 =
				// CreateEllipseJTS.createPreparedEllipticalTrajectory(t2);
				double similarity = // ((UMSMSimilarityContinuityV2)tdc).getDistance(e,t2);
						tdc.getSimilarity(t1, t2);// *-1;
				Score score = new Score(similarity, t2);
				scoreList.add(score);
				// System.out.println(similarity);
			}

			precisionAll.add(calculatePrecision(scoreList, G.stream().map(s -> ((Number) s.getTrajectoryId()).intValue()).collect(Collectors.toList())));
		}

		List<Double> avgPrecision = new ArrayList<Double>();
		double sizePrecisionList = precisionAll.get(0).size();

		for (int i = 0; i < sizePrecisionList; i++) {
			double precision = 0.0;
			for (List<Double> precisionList : precisionAll) {
				precision += precisionList.get(i);
			}
			avgPrecision.add(precision / sizePrecisionList);
		}

		for (Double d : avgPrecision) {
			System.out.println(d);
		}

		long end = System.currentTimeMillis();

		System.out.println("Elapsed time (ms): " + (end - start));
	}

	private static List<Double> calculatePrecision(List<Score> scoreList, List<Integer> groundtruth) {
		scoreList = Ordering.natural().greatestOf(scoreList, scoreList.size());
		int groundtruthSize = groundtruth.size();
		ArrayList<Double> result = new ArrayList<Double>();
		double i = 0;
		double j = 0;
		while (j < groundtruthSize && i < scoreList.size()) {

			if (groundtruth.contains(scoreList.get((int) i).getTrajectory().getTrajectoryId())) {
				j++;
				result.add(j / (i + 1));
			}
			i++;
		}
		return result;

	}

}


text:
package org.apache.tika.sax;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaCoreProperties;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

/**
 * Content handler decorator that simplifies the task of producing XHTML
 * events for Tika content parsers.
 */
public class XHTMLContentHandler extends SafeContentHandler {

    /**
     * The XHTML namespace URI
     */
    public static final String XHTML = "http://www.w3.org/1999/xhtml";

    /**
     * The newline character that gets inserted after block elements.
     */
    private static final char[] NL = new char[] { '\n' };

    /**
     * The tab character gets inserted before table cells and list items.
     */
    private static final char[] TAB = new char[] { '\t' };

    /**
     * The elements that are in the  section.
     */
    private static final Set<String> HEAD =
        unmodifiableSet("title", "link", "base", "meta", "script");

    /**
     * The elements that are automatically emitted by lazyStartHead, so
     * skip them if they get sent to startElement/endElement by mistake.
     */
    private static final Set<String> AUTO =
        unmodifiableSet("head", "frameset");

    /**
     * The elements that get prepended with the {@link #TAB} character.
     */
    private static final Set<String> INDENT =
        unmodifiableSet("li", "dd", "dt", "td", "th", "frame");

    /**
     * The elements that get appended with the {@link #NL} character.
     */
    public static final Set<String> ENDLINE = unmodifiableSet(
            "p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "ul", "ol", "dl",
            "pre", "hr", "blockquote", "address", "fieldset", "table", "form",
            "noscript", "li", "dt", "dd", "noframes", "br", "tr", "select",
            "option", "link", "script");

    private static final Attributes EMPTY_ATTRIBUTES = new AttributesImpl();

    private static Set<String> unmodifiableSet(String... elements) {
        return Collections.unmodifiableSet(
                new HashSet<String>(Arrays.asList(elements)));
    }

    /**
     * Metadata associated with the document. Used to fill in the
     * <head/> section.
     */
    private final Metadata metadata;

    /**
     * Flag to indicate whether the document has been started.
     */
    private boolean documentStarted = false;

    /**
     * Flags to indicate whether the document head element has been started/ended.
     */
    private boolean headStarted = false;
    private boolean headEnded = false;
    private boolean useFrameset = false;

    public XHTMLContentHandler(ContentHandler handler, Metadata metadata) {
        super(handler);
        this.metadata = metadata;
    }

    /**
     * Starts an XHTML document by setting up the namespace mappings
     * when called for the first time.
     * The standard XHTML prefix is generated lazily when the first
     * element is started.
     */
    @Override
    public void startDocument() throws SAXException {
    	if(!documentStarted){
    		documentStarted = true;
            super.startDocument();
            startPrefixMapping("", XHTML);
    	}
    }

    /**
     * Generates the following XHTML prefix when called for the first time:
     *

     * <html>
     *   <head>
     *     <title>...</title>
     *   </head>
     *   <body>
     *

     */
    private void lazyStartHead() throws SAXException {
        if (!headStarted) {
            headStarted = true;

            // Call directly, so we don't go through our startElement(), which will
            // ignore these elements.
            super.startElement(XHTML, "html", "html", EMPTY_ATTRIBUTES);
            newline();
            super.startElement(XHTML, "head", "head", EMPTY_ATTRIBUTES);
            newline();
        }
    }

    /**
     * Generates the following XHTML prefix when called for the first time:
     *

     * <html>
     *   <head>
     *     <title>...</title>
     *   </head>
     *   <body> (or <frameset>
     *

     */
    private void lazyEndHead(boolean isFrameset) throws SAXException {
        lazyStartHead();

        if (!headEnded) {
            headEnded = true;
            useFrameset = isFrameset;

            // TIKA-478: Emit all metadata values (other than title). We have to call
            // startElement() and characters() directly to avoid recursive problems.
            for (String name : metadata.names()) {
                if (name.equals("title")) {
                    continue;
                }

                for (String value : metadata.getValues(name)) {
                    // Putting null values into attributes causes problems, but is
                    // allowed by Metadata, so guard against that.
                    if (value != null) {
                        AttributesImpl attributes = new AttributesImpl();
                        attributes.addAttribute("", "name", "name", "CDATA", name);
                        attributes.addAttribute("", "content", "content", "CDATA", value);
                        super.startElement(XHTML, "meta", "meta", attributes);
                        super.endElement(XHTML, "meta", "meta");
                        newline();
                    }
                }
            }

            super.startElement(XHTML, "title", "title", EMPTY_ATTRIBUTES);
            String title = metadata.get(TikaCoreProperties.TITLE);
            if (title != null && title.length() > 0) {
                char[] titleChars = title.toCharArray();
                super.characters(titleChars, 0, titleChars.length);
            } else {
                // TIKA-725: Prefer <title></title> over <title/>
                super.characters(new char[0], 0, 0);
            }
            super.endElement(XHTML, "title", "title");
            newline();

            super.endElement(XHTML, "head", "head");
            newline();

            if (useFrameset) {
                super.startElement(XHTML, "frameset", "frameset", EMPTY_ATTRIBUTES);
            } else {
                super.startElement(XHTML, "body", "body", EMPTY_ATTRIBUTES);
            }
        }
    }

    /**
     * Ends the XHTML document by writing the following footer and
     * clearing the namespace mappings:
     *

     *   </body>
     * </html>
     *

     */
    @Override
    public void endDocument() throws SAXException {
        lazyEndHead(useFrameset);

        if (useFrameset) {
            super.endElement(XHTML, "frameset", "frameset");
        } else {
            super.endElement(XHTML, "body", "body");
        }

        super.endElement(XHTML, "html", "html");

        endPrefixMapping("");
        super.endDocument();
    }

    /**
     * Starts the given element. Table cells and list items are automatically
     * indented by emitting a tab character as ignorable whitespace.
     */
    @Override
    public void startElement(
            String uri, String local, String name, Attributes attributes)
            throws SAXException {

        if (name.equals("frameset")) {
            lazyEndHead(true);
        } else if (!AUTO.contains(name)) {
            if (HEAD.contains(name)) {
                lazyStartHead();
            } else {
                lazyEndHead(false);
            }

            if (XHTML.equals(uri) && INDENT.contains(name)) {
                ignorableWhitespace(TAB, 0, TAB.length);
            }

            super.startElement(uri, local, name, attributes);
        }
    }

    /**
     * Ends the given element. Block elements are automatically followed
     * by a newline character.
     */
    @Override
    public void endElement(String uri, String local, String name) throws SAXException {
        if (!AUTO.contains(name)) {
            super.endElement(uri, local, name);
            if (XHTML.equals(uri) && ENDLINE.contains(name)) {
                newline();
            }
        }
    }

    /**
     * @see TIKA-210
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        lazyEndHead(useFrameset);
        super.characters(ch, start, length);
    }

    //------------------------------------------< public convenience methods >

    public void startElement(String name) throws SAXException {
        startElement(XHTML, name, name, EMPTY_ATTRIBUTES);
    }

    public void startElement(String name, String attribute, String value)
            throws SAXException {
        AttributesImpl attributes = new AttributesImpl();
        attributes.addAttribute("", attribute, attribute, "CDATA", value);
        startElement(XHTML, name, name, attributes);
    }

    public void startElement(String name, AttributesImpl attributes)
            throws SAXException {
        startElement(XHTML, name, name, attributes);
    }

    public void endElement(String name) throws SAXException {
        endElement(XHTML, name, name);
    }

    public void characters(String characters) throws SAXException {
        if (characters != null && characters.length() > 0) {
            characters(characters.toCharArray(), 0, characters.length());
        }
    }

    public void newline() throws SAXException {
        ignorableWhitespace(NL, 0, NL.length);
    }

    /**
     * Emits an XHTML element with the given text content. If the given
     * text value is null or empty, then the element is not written.
     *
     * @param name XHTML element name
     * @param value element value, possibly null
     * @throws SAXException if the content element could not be written
     */
    public void element(String name, String value) throws SAXException {
        if (value != null && value.length() > 0) {
            startElement(name);
            characters(value);
            endElement(name);
        }
    }

}


text:
package com.coolweather.android.util;

import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;

/**
 * Created by 12098 on 2017/10/30 0030.
 */

public class HttpUtil {
    public static void sendOkHttpRequest(String url, Callback callback) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(callback);
    }
}


text:
  Bugs

    * Fix #1271: Issue deploying ReplicaSet to extensions/v1beta1

    * Fix #1152: Renamed Kubernetes RBAC resources to use non-prefixed names and renamed Openshift RBAC resources to prefix with Openshift

    * Fix #1218: CustomResourceDefinitions: cascading() causes NoSuchMethodError

    * Fix #1309: Can't get VersionInfo correctly

    * Fix #1332: Unable to use ExecCredentials

  Improvements

    * Updated compatability matrix after model upgrade in README.md

    * Fix #1306: Support `KUBECONFIG` env var with multiple paths

  Dependency Upgrade

    * Updated jackson to 2.9.8

  New Feature

    * Fix #1286: Pod Preset Support

    * Fix #1339: oAuth token rotation support

  Misc

    * Appended some files to licence check exclusion list.

#### 4.1.1

  Bugs

    * Fix #1239: Fix one case of OkHttp connection leaks

    * Fix #1266: Not setting optional Impersonate-Group results in NPE in ImpersonatorInterceptor

    * Fix #1238: Renamed files with invalid Windows characters

    * Fix #1260: Added Windows support in ConfigTest.honorClientAuthenticatorCommands

    * Fix #579: Add Timestampable interface to PodOperationsImpl/BuildOperationsImpl and set timestamps parameter

    * Fix #1273: customResources can't be used with Cluster scoped CRDs

    * Fix #1228: Closed InputStream in OperationSupport's handleResponse to avoid leak

    * Fix #1280: Fix ExecCredential deserialization in kubeconfig auth

  Improvements

    * Fix #1226 : Extend and move integrations tests

    * Fix #989  : Add support for waitForCondition

    * Fix #1293 : OpenShiftOAuthInterceptor.authorize() should only throw IOException

  Dependency Upgrade

    * Fix #1223: jackson-dataformat-yaml dependency (2.7.7) ageing

    * Fix #1262: Upgrade maven-surefire-plugin to 3.0.0-M1

    * Fix #1272: Upgrade Awaitility to version 3.1.3

    * Fix #1235: Upgrade kubernetes-model to latest kubernetes/Openshift versions

  New Feature
    * Fix #1142: Pagination Support

    * Fix #1234: VolumeNodeAffinity support

    * Fix #1244: Pod Priority Support

    * Fix #1186: Added Support for creating HPA based on custom metrics

#### 4.0.7
  Bugs

    * Fix #1214 : Watch resource versions not correctly tracked resulting in 410 errors on reconnect

  Improvements

    * Fix #1179 : Impersonate-Extra keys may be specified multiple times
    * Fix #1182 : Fixes flaky integration tests.
    * Fix #1200 : Support client authenticator commands like `aws-iam-authenticator`.
    * Fix #1201 : Fix problems with swallowed InterruptedExceptions
    * Chore #1168 : Upgrade to Java 8
    * fix #1197 : Broken withName() method  for CustomResourceDefinition.

  Dependency Upgrade

  New Feature

#### 4.0.4
  Bugs

    * Fix #1180 : DeploymentExamples requires the definition of a selector with match labels

    * Fix #1099 : CustomResourceDefinitions: withResourceVersion() causes NoSuchMethodError

    * Fix #1156 : Watcher does not have correct authentication information in Openshift environment.

    * Fix #1125 : ConfigMap labels are ignored when using mock KubernetesServer

    * Fix #1144 : Get Request with OpenShift Mock Server Not Working

    * Fix #1147 : Cluster context was being ignored when loading the Config from a kubeconfig file

    * Fix #1162 : Deletion of DeploymentConfig now does not fail randomly because of issues related to owner references of the ReplicationController

    * Fix #1165 : Null parameter values when processing a template are now handled properly

    * Fix #1173 : Send response to Callback for exec commands that have no textual feedback

    * Fix #1172 : Use v1beta1 for CronJob

    * Fix #1158: Add support for label selectors in the mock server

  Improvements

    * Added Kubernetes/Openshift examples for client.getVersion()
    * Fix #1126 : Add new option `kubernetes.disable.hostname.verification` / `KUBERNETES_DISABLE_HOSTNAME_VERIFICATION` to disable hostname verification
    * Fix #1178 : Impersonate-Group may be specified multiple times

  Dependency Upgrade

    * Fix #924 : Include kubernetes-model in client BOM with dependencies.

  New Feature

    * Fix #1066 : Add support for Kubernetes RBAC Role and Role Binding
    * Fix #1150: Add support for Kubernetes RBAC Cluster Role and Cluster Role Binding
    * Fix #770: Added Support for CronJob
    * Fix #1140: Provide User Utilities
    * Fix #1139 : Make it easy to get the URL of a service.

#### 4.0.0
  Bugs

    * Fix #1098 : Unable to create LimitRange from yaml
    * Fix #1089 : Query parameters are not correctly processed if set in `masterUrl`
    * Fix #1112 : Append multiple query param in masterUrl
    * Fix #1085 : Impersonate parameters are not configurable for DefaultOpenShiftClient
    * Fix #1106 : Fix typo in crud mode in mockserver

  New Feature

    * Fix #1020 : Support for Kubernetes/Openshift v1.9/v3.9 respectively

  Improvements

    * Fix #1119 : Regression Test are more stable and takes less time to execute

  Dependency Upgrade

    * Kubernetes Model upgraded to 3.0.0 with support for Kubernetes/Openshift v1.9/v3.9 respectively
      Features and Fixes Available
       * Resources according to Kubernetes/Openshift v1.9/v3.9
       * Add support for RBAC Role, Role Binding and Netnamespace in Model
       * KubernetesDeserializer shouldn't pickup mappings from incompatible providers
       * Add all packages in KubernetesDeserializer

  Major Movements and Changes

    * SecurityContextConstraints has been moved to OpenShift client from Kubernetes Client
    * Job dsl is in both `batch` and `extensions`(Extensions is deprecated)
    * DaemonSet dsl is in both `apps` and `extensions`(Extensions is deprecated)
    * Deployment dsl is in both `apps` and `extensions`(Extensions is deprecated)
    * ReplicaSet dsl is in both `apps` and `extensions`(Extensions is deprecated)
    * NetworkPolicy dsl is in both `network` and `extensiosn`(Extensions is deprecated)
    * Storage Class moved from `client base DSL` to `storage` DSL
    * PodSecurityPolicies moved from `client base DSL` and `extensions` to only `extensions`
    * ThirdPartyResource has been removed.

#### 3.2.0
  Bugs
   * Fix #1083 : Mock Kubernetes server only handles core and extensions API groups
   * Fix #1087 : Mock server can't list custom resources
   * Fix #1055 : Unable to log in to cluster when using username and password

  New Feature
   * Support `error` websocket channel - https://github.com/fabric8io/kubernetes-client/pull/1045

  Improvements
   * Do not repeatedly create Config instance in exec - https://github.com/fabric8io/kubernetes-client/pull/1081
   * Determine kubernetes service host and port from environment if available - https://github.com/fabric8io/kubernetes-client/pull/1086
   * Upgraded Kuberneted Model version to 2.1.1
     Features and Fixes Available
      * KubernetesDeserializer can now lookup for resource mappings via ServiceLoader - https://github.com/fabric8io/kubernetes-model/pull/307
      * Add new package to OSGi exports - https://github.com/fabric8io/kubernetes-model/pull/310
      * Add additional types that are needed to support extensions - https://github.com/fabric8io/kubernetes-model/pull/305

#### 3.1.12
  Bugs
   * Fix #1070 : Error parsing openshift json template with the latest version

  New Feature
   * Fix #1048 : Add support for the k8s/openshift version

  Improvements
   * Fixes premature call to watcher onClose

#### 3.1.11
  Bugs
   * Fix #1013 : Kubernetes connection is not getting closed.
   * Fix #1004 : Multiple document handling breaks if "---" found anywhere in the document
   * Fix #1035 : RejectedExecutionException in WatchHTTPManager
   * Impersonation parameters not set in withRequestConfig - https://github.com/fabric8io/kubernetes-client/pull/1037

  Improvements
   * NO_PROXY setting now supports IP ranges so you can specify whole subnet to be excluded from proxy traffic eg. 192.168.0.1/8

#### 3.1.10
  Bugs

  New Feature
   * Added support for StorageClass - https://github.com/fabric8io/kubernetes-client/pull/978
   * Added support for PodSecurityPolicy - https://github.com/fabric8io/kubernetes-client/pull/992
   * The client now warns when using Kubernetes alpha or beta resources - https://github.com/fabric8io/kubernetes-client/pull/1010
   * A Config can now be built from `Config.fromKubeconfig(kubeconfigFileContents)`: https://github.com/fabric8io/kubernetes-client/pull/1029

  Improvements
   * Fixed issue of SecurityContextConstraints not working - https://github.com/fabric8io/kubernetes-client/pull/982
	Note :- This got fixed by fixing model - https://github.com/fabric8io/kubernetes-model/pull/274
  Dependencies Upgrade


text:
(function () {
    /**
     * Single Particle Object.
     * @class
     * @extends me.Renderable
     * @memberOf me
     * @constructor
     * @param {me.ParticleEmitter} particle emitter
     */
    me.Particle = me.Renderable.extend(
    /** @scope me.Particle.prototype */
    {
        /**
         * @ignore
         */
        init : function (emitter) {
            // Call the super constructor
            var point = emitter.getRandomPoint();
            this._super(me.Renderable, "init", [point.x, point.y, emitter.image.width, emitter.image.height]);

            // Particle will always update
            this.alwaysUpdate = true;

            // Particle will not act as a rednerable
            // FIXME: This is probably not needed. It's a hack that tries to
            // workaround performance issues within container.
            this.isRenderable = false;

            // Cache the image reference
            this.image = emitter.image;

            // Set the start particle Angle and Speed as defined in emitter
            var angle = emitter.angle + ((emitter.angleVariation > 0) ? ((0).randomFloat(2) - 1) * emitter.angleVariation : 0);
            var speed = emitter.speed + ((emitter.speedVariation > 0) ? ((0).randomFloat(2) - 1) * emitter.speedVariation : 0);

            // Set the start particle Velocity
            this.vel = new me.Vector2d(speed * Math.cos(angle), -speed * Math.sin(angle));

            // Set the start particle Time of Life as defined in emitter
            this.life = emitter.minLife.randomFloat(emitter.maxLife);
            this.startLife = this.life;

            // Set the start and end particle Scale as defined in emitter
            // clamp the values as minimum and maximum scales range
            this.startScale = emitter.minStartScale.randomFloat(
                emitter.maxStartScale
            ).clamp(emitter.minStartScale, emitter.maxStartScale);
            this.endScale = emitter.minEndScale.randomFloat(
                emitter.maxEndScale
            ).clamp(emitter.minEndScale, emitter.maxEndScale);

            // Set the particle Gravity and Wind (horizontal gravity) as defined in emitter
            this.gravity = emitter.gravity;
            this.wind = emitter.wind;

            // Set if the particle update the rotation in accordance the trajectory
            this.followTrajectory = emitter.followTrajectory;

            // Set if the particle update only in Viewport
            this.onlyInViewport = emitter.onlyInViewport;

            // Set the particle Z Order
            this.z = emitter.z;

            // cache inverse of the expected delta time
            this._deltaInv = me.sys.fps / 1000;

            this.transform = new me.Matrix2d();

            // Set the start particle rotation as defined in emitter
            // if the particle not follow trajectory
            if (!emitter.followTrajectory) {
                this.angle = emitter.minRotation.randomFloat(emitter.maxRotation);
            }
        },

        /**
         * Update the Particle <br>
         * This is automatically called by the game manager {@link me.game}
         * @name update
         * @memberOf me.Particle
         * @function
         * @ignore
         * @param {Number} dt time since the last update in milliseconds
         */
        update : function (dt) {
            // move things forward independent of the current frame rate
            var skew = dt * this._deltaInv;

            // Decrease particle life
            this.life = this.life > dt ? this.life - dt : 0;

            // Calculate the particle Age Ratio
            var ageRatio = this.life / this.startLife;

            // Resize the particle as particle Age Ratio
            var scale = this.startScale;
            if (this.startScale > this.endScale) {
                scale *= ageRatio;
                scale = (scale < this.endScale) ? this.endScale : scale;
            }
            else if (this.startScale < this.endScale) {
                scale /= ageRatio;
                scale = (scale > this.endScale) ? this.endScale : scale;
            }

            // Set the particle opacity as Age Ratio
            this.alpha = ageRatio;

            // Adjust the particle velocity
            this.vel.x += this.wind * skew;
            this.vel.y += this.gravity * skew;

            // If necessary update the rotation of particle in accordance the particle trajectory
            var angle = this.followTrajectory ? Math.atan2(this.vel.y, this.vel.x) : this.angle;

            this.pos.x += this.vel.x * skew;
            this.pos.y += this.vel.y * skew;

            // Update particle transform
            this.transform.set(
                scale, 0, 0,
                0, scale, 0,
                ~~this.pos.x, ~~this.pos.y, 1
            ).rotate(angle);

            // Return true if the particle is not dead yet
            return (this.inViewport || !this.onlyInViewport) && (this.life > 0);
        },

        draw : function (renderer) {
            renderer.save();

            // particle alpha value
            renderer.setGlobalAlpha(renderer.globalAlpha() * this.alpha);

            // translate to the defined anchor point and scale it
            renderer.transform(this.transform);

            var w = this.width, h = this.height;
            renderer.drawImage(
                this.image,
                0, 0,
                w, h,
                -w / 2, -h / 2,
                w, h
            );

            renderer.restore();
        }
    });

    /*---------------------------------------------------------*/
    // END END END
    /*---------------------------------------------------------*/
})(window);


text:
#include <acsdk/Test/GmockExtensions.h>

namespace alexaClientSDK {
namespace test {

using namespace ::testing;

/**
 * @brief Interface with noexcept and const noexcept methods.
 */
class SomeInterface {
public:
    virtual ~SomeInterface() noexcept = default;
    virtual int noexceptMethod0() noexcept = 0;
    virtual int noexceptMethod1(int) noexcept = 0;
    virtual int noexceptMethod2(int, int) noexcept = 0;
    virtual int noexceptMethod3(int, int, int) noexcept = 0;
    virtual int noexceptMethod4(int, int, int, int) noexcept = 0;
    virtual int noexceptMethod5(int, int, int, int, int) noexcept = 0;
    virtual int noexceptMethod6(int, int, int, int, int, int) noexcept = 0;
    virtual int noexceptMethod7(int, int, int, int, int, int, int) noexcept = 0;
    virtual int noexceptMethod8(int, int, int, int, int, int, int, int) noexcept = 0;
    virtual int noexceptMethod9(int, int, int, int, int, int, int, int, int) noexcept = 0;
    virtual int noexceptMethod10(int, int, int, int, int, int, int, int, int, int) noexcept = 0;
    virtual int constNoexceptMethod0() const noexcept = 0;
    virtual int constNoexceptMethod1(int) const noexcept = 0;
    virtual int constNoexceptMethod2(int, int) const noexcept = 0;
    virtual int constNoexceptMethod3(int, int, int) const noexcept = 0;
    virtual int constNoexceptMethod4(int, int, int, int) const noexcept = 0;
    virtual int constNoexceptMethod5(int, int, int, int, int) const noexcept = 0;
    virtual int constNoexceptMethod6(int, int, int, int, int, int) const noexcept = 0;
    virtual int constNoexceptMethod7(int, int, int, int, int, int, int) const noexcept = 0;
    virtual int constNoexceptMethod8(int, int, int, int, int, int, int, int) const noexcept = 0;
    virtual int constNoexceptMethod9(int, int, int, int, int, int, int, int, int) const noexcept = 0;
    virtual int constNoexceptMethod10(int, int, int, int, int, int, int, int, int, int) const noexcept = 0;
};

/**
 * @brief Mock for @c SomeInterface.
 */
class SomeMock : public SomeInterface {
public:
    MOCK_NOEXCEPT_METHOD0(noexceptMethod0, int());
    MOCK_NOEXCEPT_METHOD1(noexceptMethod1, int(int));
    MOCK_NOEXCEPT_METHOD2(noexceptMethod2, int(int, int));
    MOCK_NOEXCEPT_METHOD3(noexceptMethod3, int(int, int, int));
    MOCK_NOEXCEPT_METHOD4(noexceptMethod4, int(int, int, int, int));
    MOCK_NOEXCEPT_METHOD5(noexceptMethod5, int(int, int, int, int, int));
    MOCK_NOEXCEPT_METHOD6(noexceptMethod6, int(int, int, int, int, int, int));
    MOCK_NOEXCEPT_METHOD7(noexceptMethod7, int(int, int, int, int, int, int, int));
    MOCK_NOEXCEPT_METHOD8(noexceptMethod8, int(int, int, int, int, int, int, int, int));
    MOCK_NOEXCEPT_METHOD9(noexceptMethod9, int(int, int, int, int, int, int, int, int, int));
    MOCK_NOEXCEPT_METHOD10(noexceptMethod10, int(int, int, int, int, int, int, int, int, int, int));

    MOCK_CONST_NOEXCEPT_METHOD0(constNoexceptMethod0, int());
    MOCK_CONST_NOEXCEPT_METHOD1(constNoexceptMethod1, int(int));
    MOCK_CONST_NOEXCEPT_METHOD2(constNoexceptMethod2, int(int, int));
    MOCK_CONST_NOEXCEPT_METHOD3(constNoexceptMethod3, int(int, int, int));
    MOCK_CONST_NOEXCEPT_METHOD4(constNoexceptMethod4, int(int, int, int, int));
    MOCK_CONST_NOEXCEPT_METHOD5(constNoexceptMethod5, int(int, int, int, int, int));
    MOCK_CONST_NOEXCEPT_METHOD6(constNoexceptMethod6, int(int, int, int, int, int, int));
    MOCK_CONST_NOEXCEPT_METHOD7(constNoexceptMethod7, int(int, int, int, int, int, int, int));
    MOCK_CONST_NOEXCEPT_METHOD8(constNoexceptMethod8, int(int, int, int, int, int, int, int, int));
    MOCK_CONST_NOEXCEPT_METHOD9(constNoexceptMethod9, int(int, int, int, int, int, int, int, int, int));
    MOCK_CONST_NOEXCEPT_METHOD10(constNoexceptMethod10, int(int, int, int, int, int, int, int, int, int, int));
};

/**
 * @brief Test fixture for testing GMock extensions.
 */
class GmockExtensionsTest : public ::testing::Test {};

TEST_F(GmockExtensionsTest, test_noexceptMethod0) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod0()).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod0());
};

TEST_F(GmockExtensionsTest, test_noexceptMethod1) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod1(1)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod1(1));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod2) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod2(1, 2)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod2(1, 2));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod3) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod3(1, 2, 3)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod3(1, 2, 3));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod4) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod4(1, 2, 3, 4)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod4(1, 2, 3, 4));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod5) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod5(1, 2, 3, 4, 5)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod5(1, 2, 3, 4, 5));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod6) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod6(1, 2, 3, 4, 5, 6)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod6(1, 2, 3, 4, 5, 6));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod7) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod7(1, 2, 3, 4, 5, 6, 7)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod7(1, 2, 3, 4, 5, 6, 7));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod8) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod8(1, 2, 3, 4, 5, 6, 7, 8)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod8(1, 2, 3, 4, 5, 6, 7, 8));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod9) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod9(1, 2, 3, 4, 5, 6, 7, 8, 9)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod9(1, 2, 3, 4, 5, 6, 7, 8, 9));
};

TEST_F(GmockExtensionsTest, test_noexceptMethod10) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod0) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod0()).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod0());
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod1) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod1(1)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod1(1));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod2) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod2(1, 2)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod2(1, 2));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod3) {
    SomeMock mock;
    EXPECT_CALL(mock, noexceptMethod3(1, 2, 3)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.noexceptMethod3(1, 2, 3));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod4) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod4(1, 2, 3, 4)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod4(1, 2, 3, 4));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod5) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod5(1, 2, 3, 4, 5)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod5(1, 2, 3, 4, 5));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod6) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod6(1, 2, 3, 4, 5, 6)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod6(1, 2, 3, 4, 5, 6));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod7) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod7(1, 2, 3, 4, 5, 6, 7)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod7(1, 2, 3, 4, 5, 6, 7));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod8) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod8(1, 2, 3, 4, 5, 6, 7, 8)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod8(1, 2, 3, 4, 5, 6, 7, 8));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod9) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod9(1, 2, 3, 4, 5, 6, 7, 8, 9)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod9(1, 2, 3, 4, 5, 6, 7, 8, 9));
};

TEST_F(GmockExtensionsTest, test_constNoexceptMethod10) {
    SomeMock mock;
    EXPECT_CALL(mock, constNoexceptMethod10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)).Times(1).WillOnce(Return(-5));
    ASSERT_EQ(-5, mock.constNoexceptMethod10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
};

}  // namespace test
}  // namespace alexaClientSDK


text:
// Copyright 2007-2011 Chris Patterson, Dru Sellers, Travis Smith, et. al.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

using Burrows.Configuration.Builders;
using Burrows.Configuration.Configurators;
using Burrows.Endpoints;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Burrows.Configuration.EndpointConfigurators
{
    /// <summary>
	/// Allows for the configuration of the EndpointFactory through the use of an EndpointFactoryConfigurator
	/// </summary>
	public interface IEndpointFactoryConfigurator :
		IConfigurator
	{
		/// <summary>
		/// Gets the endpoint factory defaults.
		/// </summary>
		IEndpointFactoryDefaultSettings Defaults { get; }

		/// <summary>
		/// Creates the endpoint factory with the configuration
		/// </summary>
		/// <returns></returns>
		IEndpointFactory CreateEndpointFactory();

		/// <summary>
		/// Overrides the default EndpointResolver builder with another builder
		/// </summary>
		/// <param name="endpointFactoryBuilderFactory"></param>
		void UseEndpointFactoryBuilder(Func<IEndpointFactoryDefaultSettings, IEndpointFactoryBuilder> endpointFactoryBuilderFactory);

		/// <summary>
		/// Adds an endpoint configurator to the endpoint resolver builder
		/// </summary>
		/// <param name="configurator"></param>
		void AddEndpointFactoryConfigurator(IEndpointFactoryBuilderConfigurator configurator);
	}

	public class EndpointFactoryConfigurator :
		IEndpointFactoryConfigurator
	{
		readonly EndpointFactoryDefaultSettings _defaultSettings;
		readonly IList<IEndpointFactoryBuilderConfigurator> _endpointFactoryConfigurators;
		Func<IEndpointFactoryDefaultSettings, IEndpointFactoryBuilder> _endpointFactoryBuilderFactory;

		public EndpointFactoryConfigurator(EndpointFactoryDefaultSettings defaultSettings)
		{
			_defaultSettings = defaultSettings;
			_endpointFactoryBuilderFactory = DefaultEndpointResolverBuilderFactory;
			_endpointFactoryConfigurators = new List<IEndpointFactoryBuilderConfigurator>();
		}

		public IEnumerable<IValidationResult> Validate()
		{
			if (_endpointFactoryBuilderFactory == null)
				yield return this.Failure("BuilderFactory", "The builder factory was null. Since this came from a 'Default' this is spooky.");

			foreach (var result in _endpointFactoryConfigurators.SelectMany(configurator => configurator.Validate()))
				yield return result.WithParentKey("EndpointFactory");
		}

		public void UseEndpointFactoryBuilder(Func<IEndpointFactoryDefaultSettings, IEndpointFactoryBuilder> endpointFactoryBuilderFactory)
		{
			_endpointFactoryBuilderFactory = endpointFactoryBuilderFactory;
		}

		public void AddEndpointFactoryConfigurator(IEndpointFactoryBuilderConfigurator configurator)
		{
			_endpointFactoryConfigurators.Add(configurator);
		}

		public IEndpointFactoryDefaultSettings Defaults
		{
			get { return _defaultSettings; }
		}

		public IEndpointFactory CreateEndpointFactory()
		{
			IEndpointFactoryBuilder builder = _endpointFactoryBuilderFactory(_defaultSettings);

			foreach (IEndpointFactoryBuilderConfigurator configurator in _endpointFactoryConfigurators)
			{
				builder = configurator.Configure(builder);
			}

			return builder.Build();
		}

		static IEndpointFactoryBuilder DefaultEndpointResolverBuilderFactory(IEndpointFactoryDefaultSettings defaults)
		{
			return new EndpointFactoryBuilder(defaults);
		}
	}
}