text:
#include "../include/DarcyFractured.h"

/**************************************************************************/
/*  DarcyFractured.cc													  */
/*  Classe che assembla e risolve il sistema per il problema di Darcy	  */
/*  sulle fratture											              */
/**************************************************************************/

DarcyFractured::DarcyFractured ( const MediumDataPtr_Type& medium,
                                 const MeshHandlerPtr_Type& mesh,
                                 const BCHandlerPtr_Type& bcHandler,
                                 const FracturesSetPtr_Type& fractures,
                                 const ExporterPtr_Type& exporter ) :
            M_mediumData ( medium ),
            M_mesh ( mesh ),
            M_bcHandler ( bcHandler ),
            M_fractures ( fractures ),
            M_exporter ( exporter ),
            M_fractureEtaNormalOnMedium ( M_fractures->getNumberFractures () ),
            M_fractureVelocity ( M_fractures->getNumberFractures () ),
            M_fracturePressure ( M_fractures->getNumberFractures () )
{} // costruttore

void DarcyFractured::init ( )
{

    // Alloco i dati
    const size_type shifCoefficients = M_mesh->getMeshFEMCoefficients().nb_dof();

    const size_type numberFractures = M_fractures->getNumberFractures();

    for ( size_type f = 0; f < numberFractures; ++f )
    {
        // Alloco il vettore per M_fracturesEtaNormalOnMedium
        gmm::resize(M_fractureEtaNormalOnMedium [ f ], shifCoefficients);
        gmm::clear(M_fractureEtaNormalOnMedium [ f ]);

    }

    return;

} // init

void DarcyFractured::assembly ( const GetPot& dataFile )
{
	// numero totale delle fratture
    const scalar_type numberFractures = M_fractures->getNumberFractures();

    // vettore dei gradi di libertà per la pressione per le fratture
    sizeVector_Type fractureNumberDOFPressure(numberFractures);

    // numero di gradi di libertà totali per la pressione (con quelli estesi) per ogni frattura
    sizeVector_Type fractureNumberGlobalDOFPressure(numberFractures);

    // vettore dei gradi di libertà per la velocità per le fratture
    sizeVector_Type fractureNumberDOFVelocity(numberFractures);

    // numero di gradi di libertà totali per la velocità (con quelli estesi) per ogni frattura
    sizeVector_Type fractureNumberGlobalDOFVelocity(numberFractures);

    // numero totale dei gradi di libertà ( velocità + pressione ) per ogni frattura
    sizeVector_Type fractureNumberDOFVelocityPressure(numberFractures);

    // numero di gradi di libertà vincolati alla condizione al bordo per ogni frattura
    sizeVector_Type fractureNumberBoundaryDOF(numberFractures);

    // numero complessivo dei gradi di libertà ( pressione + velocità )
    size_type fractureTotalNumberDOFVelocityPressure = 0;

    // numero complessivo dei gradi di libertà di pressione
    size_type fractureTotalNumberDOFPressure = 0;

    // numero totale di intersezioni
    size_type fractureNumberCross = 0;
    size_type fractureNumberBifurcation = 0;
	size_type fractureNumberBifurcation2 = 0;
    size_type globalFractureNumber =0;

    for ( size_type f = 0; f < numberFractures; ++f )
    {
    	// numero di gradi di libertà per la pressione senza quelli estesi per la frattura f
        fractureNumberDOFPressure [ f ] = M_fractures->getFracture( f )->getMeshFEMPressure().nb_dof();

    	// numero di gradi di libertà per la pressione con quelli estesi per la frattura f
        fractureNumberGlobalDOFPressure [ f ] = fractureNumberDOFPressure [ f ] + M_fractures->getFracture( f )->getNumExtendedPressure();

    	// numero totale di gradi di libertà per la pressione
        fractureTotalNumberDOFPressure += fractureNumberGlobalDOFPressure [ f ];

    	// numero di gradi di libertà per la velocità senza quelli estesi per la frattura f
        fractureNumberDOFVelocity [ f ] = M_fractures->getFracture( f )->getMeshFEMVelocity().nb_dof();

    	// numero di gradi di libertà per la velocità con quelli estesi per la frattura f
        fractureNumberGlobalDOFVelocity [ f ] = fractureNumberDOFVelocity [ f ] + M_fractures->getFracture( f )->getNumExtendedVelocity();

    	// numero totale di gradi di libertà per la velocità e la pressione per la frattura f
        fractureNumberDOFVelocityPressure [ f ] = fractureNumberGlobalDOFVelocity [ f ] + fractureNumberGlobalDOFPressure [ f ];

    	// numero totale di gradi di libertà per la pressione e la velocità
        fractureTotalNumberDOFVelocityPressure += fractureNumberDOFVelocityPressure [ f ];

    	// numero di gradi di libertà per i bordi per la frattura f
        fractureNumberBoundaryDOF [ f ] = M_bcHandler->getFractureBC(f)->getMeshFEM().nb_dof();

    }

    // Numero intersezioni
    fractureNumberCross = M_fractures->getIntersections ()->getNumberCross ();

    fractureNumberBifurcation = M_fractures->getIntersections ()->getNumberBifurcation ();

	fractureNumberBifurcation2 = M_fractures->getIntersections ()->getNumberBifurcation2 ();

    globalFractureNumber = fractureNumberCross*2 + fractureNumberBifurcation + 2*fractureNumberBifurcation2;

    // Inizializziamo tutte le matrici a blocchi, la matrice globale e il termine di destra per il sistema e il vettore delle soluzioni

    // Allochiamo la matrice globale del sistema:  M_darcyGlobalMatrix
    M_globalMatrix.reset( new sparseMatrix_Type( fractureTotalNumberDOFVelocityPressure + globalFractureNumber,
             	 	 	 	 	 	 	 	 	 fractureTotalNumberDOFVelocityPressure + globalFractureNumber ));

    gmm::clear( *M_globalMatrix );

    // Allochiamo il vettore del termine noto di destra del sistema: M_darcyGlobalRightHandSide
    M_globalRightHandSide.reset( new scalarVector_Type( fractureTotalNumberDOFVelocityPressure + globalFractureNumber ));
    gmm::clear( *M_globalRightHandSide );

    // Allochiamo il vettore globale del termine incognito del sistema: M_darcyVelocityAndPressure
    M_velocityAndPressure.reset(new scalarVector_Type( fractureTotalNumberDOFVelocityPressure + globalFractureNumber ));
    gmm::clear(*M_velocityAndPressure);

    // Allochiamo la matrice che usereme per accoppiare le fratture che si intersecano
    sparseMatrixPtr_Type  App;

    App.reset(new sparseMatrix_Type( fractureNumberCross , 2*fractureNumberCross ));
       gmm::clear(*App);

    // Matrici a blocchi per le fratture
    sparseMatrixPtrContainer_Type A11F(numberFractures), A12F(numberFractures);

    for ( size_type f = 0; f < numberFractures; ++f )
    {
        // Alloco la matrice A11F per la fratture f-esima
        A11F [ f ].reset(new sparseMatrix_Type ( fractureNumberGlobalDOFVelocity [ f ], fractureNumberGlobalDOFVelocity [ f ]) );
        gmm::clear(*(A11F [ f ]));

        // Alloco la matrice A12F per la fratture f-esima
        A12F [ f ].reset(new sparseMatrix_Type ( fractureNumberGlobalDOFVelocity [ f ], fractureNumberGlobalDOFPressure [ f ]) );
        gmm::clear(*(A12F [ f ]));
    }

    // Accoppio le fratture
    getfem::coupleFractures ( App, M_fractures, 1 );
    sizeVector_Type shiftIntersect ( numberFractures );

    shiftIntersect [ 0 ] = 0;

    // Calcolo i blocchi di matrici per ogni frattura
    for ( size_type f = 0; f < numberFractures; ++f )
    {
        std::cout <<std::endl<< "Fracture " << f << std::endl;

        // Computes the matrix \int_\gamma \tau_i \cdot \tau_j
        getfem::darcy_A11F ( A11F [ f ], M_fractures->getFracture( f ),
                             M_mediumData->getPenaltyVector(),
                             M_fractures->getFracture( f )->getEtaTangentialInterpolated(),
                             M_bcHandler->getFractureBC(f)->getDirichlet(), FractureHandler::FRACTURE_UNCUT * ( f + 1 ) );

        // Computes the matrix \int_\gamma \nabla v_i \cdot \tau_j
        getfem::darcy_A12F ( A12F [ f ], M_fractures->getFracture( f ), FractureHandler::FRACTURE_UNCUT * ( f + 1 ) );

        if( f != 0)
        {
        	shiftIntersect [ f ] = shiftIntersect [ f-1 ] + fractureNumberDOFVelocityPressure [ f-1 ];
        }

    }

    std::cout << std::endl;

    // Introduco il termine legato all'intersezione
    // A seconda del tipo di intersezione, Cross o Biforcazione, devo introdurre dei termini diversi

    IntersectDataContainer_Type IntCross = M_fractures->getIntersections ()-> getCrossIntersections ();

    IntersectDataContainer_Type IntBifurcation = M_fractures->getIntersections ()-> getBifurcationIntersections ();

    IntersectDataContainer_Type IntBifurcation2 = M_fractures->getIntersections ()-> getBifurcation2Intersections ();

    // Aggiorno prima le matrici di tutte le fratture che si intersecano formando un " Cross "
    for ( size_type i = 0; i < IntCross.size(); i++ )
    {
    	sparseMatrixPtr_Type Aup0, Aup1;

    	FractureHandlerPtr_Type f0 = IntCross [ i ].getFracture (0);
    	FractureHandlerPtr_Type f1 = IntCross [ i ].getFracture (1);

    	size_type id0 = f0->getId();
    	size_type id1 = f1->getId();

        std::cout << "Cross: " << std::endl;
		std::cout << " Fractures " << id0 << ", " << id1 << std::endl;

        Aup0.reset ( new sparseMatrix_Type ( fractureNumberGlobalDOFVelocity [ id0 ], 1 ) );
        gmm::clear(*Aup0);

        Aup1.reset ( new sparseMatrix_Type ( fractureNumberGlobalDOFVelocity [ id1 ], 1 ) );
        gmm::clear(*Aup1);

        // aggiorno per la frattura 0
        getfem::darcy_A11F_Cross ( A11F [ id0 ],f0,
								   f0->getEtaTangentialInterpolated(),
								   f1,
								   FractureHandler::FRACTURE_INTERSECT * ( id0 + 1 ) + id1 + 1);

        getfem::darcy_A12F_Cross ( A12F [ id0 ], f0, f1,
                             	   FractureHandler::FRACTURE_INTERSECT * ( id0 + 1 ) + id1 + 1 );
        std::cout << std::endl;

        // aggiorno per la frattura 1
        getfem::darcy_A11F_Cross ( A11F [ id1 ],f1,
							 	   f1->getEtaTangentialInterpolated(),
							 	   f0,
							 	   FractureHandler::FRACTURE_INTERSECT * ( id1 + 1 ) + id0 + 1 );

		getfem::darcy_A12F_Cross ( A12F [ id1 ], f1, f0,
								   FractureHandler::FRACTURE_INTERSECT * ( id1 + 1 ) + id0 + 1 );

		std::cout << std::endl;

        const pairSizeVectorContainer_Type& intersectElementsGlobalIndex0 = f0->getFractureIntersectElementsGlobalIndex ();

        const size_type numIntersections = intersectElementsGlobalIndex0 [id1].size();

        const sizeVectorContainer_Type& intersectElements0 = f0->getFractureIntersectElements ();
        const sizeVectorContainer_Type& intersectElements1 = f1->getFractureIntersectElements ();

		for ( size_type k = 0; k < numIntersections; ++k )
		{
			gmm::clear (*Aup0);
			gmm::clear (*Aup1);

			getfem::velocityJump_Cross ( Aup0, f0, f1, intersectElements0 [ id1 ][ k ] );
			getfem::velocityJump_Cross ( Aup1, f1, f0, intersectElements1 [ id0 ][ k ] );

			const size_type globalIndex = intersectElementsGlobalIndex0 [ id1 ] [ k ].first;
			const size_type globalIndex2 = intersectElementsGlobalIndex0 [ id1 ] [ k ].second;

			gmm::copy ( *Aup0,
					    gmm::sub_matrix (*M_globalMatrix,
									    gmm::sub_interval ( shiftIntersect [ id0 ], fractureNumberGlobalDOFVelocity [ id0 ] ),
									    gmm::sub_interval (  fractureTotalNumberDOFVelocityPressure + globalIndex, 1 ) ) );

			gmm::copy ( gmm::transposed(*Aup0),
					    gmm::sub_matrix (*M_globalMatrix,
									    gmm::sub_interval (  fractureTotalNumberDOFVelocityPressure + fractureNumberCross + std::min(globalIndex, globalIndex2), 1 ),
									    gmm::sub_interval ( shiftIntersect [ id0 ], fractureNumberGlobalDOFVelocity [ id0 ] ) ) );

			gmm::copy ( *Aup1,
					    gmm::sub_matrix (*M_globalMatrix,
									    gmm::sub_interval ( shiftIntersect [ id1 ], fractureNumberGlobalDOFVelocity [ id1 ] ),
									    gmm::sub_interval (  fractureTotalNumberDOFVelocityPressure + globalIndex2, 1 ) ) );

			gmm::copy ( gmm::transposed(*Aup1),
					    gmm::sub_matrix (*M_globalMatrix,
									    gmm::sub_interval (  fractureTotalNumberDOFVelocityPressure + fractureNumberCross + std::min(globalIndex, globalIndex2), 1 ),
									    gmm::sub_interval ( shiftIntersect [ id1 ], fractureNumberGlobalDOFVelocity [ id1 ] ) ) );

         }

    }

    // Aggiorno prima le matrici di tutte le fratture che si intersecano formando un " IntBifurcation2 "
	for ( size_type i = 0; i < IntBifurcation2.size(); i++ )
	{
		sparseMatrixPtr_Type Aup0;

		// frattura lunga
		FractureHandlerPtr_Type f0, f1;

		if( IntBifurcation2 [ i ].getFracture (0)->getDOFBifurcation().size() != 0 )
		{
			f0 = IntBifurcation2 [ i ].getFracture (0);
			f1 = IntBifurcation2 [ i ].getFracture (1);
		}
		else
		{
			f0 = IntBifurcation2 [ i ].getFracture (1);
			f1 = IntBifurcation2 [ i ].getFracture (0);
		}

		size_type id0 = f0->getId();
		size_type id1 = f1->getId();

		Aup0.reset ( new sparseMatrix_Type ( fractureNumberGlobalDOFVelocity [ id0 ], 1 ) );
		gmm::clear(*Aup0);

		// aggiorno per la frattura 0
		getfem::darcy_A11F_Cross ( A11F [ id0 ],f0,
								   f0->getEtaTangentialInterpolated(),
								   f1,
								   FractureHandler::FRACTURE_INTERSECT * ( id0 + 1 ) + id1 + 1);

		getfem::darcy_A12F_Cross ( A12F [ id0 ], f0, f1,
								   FractureHandler::FRACTURE_INTERSECT * ( id0 + 1 ) + id1 + 1 );

		const pairSizeVectorContainer_Type& intersectElementsGlobalIndex0 = f0->getFractureIntersectElementsGlobalIndex ();

		const size_type numIntersections = intersectElementsGlobalIndex0 [id1].size();

		const sizeVectorContainer_Type& intersectElements0 = f0->getFractureIntersectElements ();

		for ( size_type k = 0; k < numIntersections; ++k )
		{
			gmm::clear (*Aup0);

			getfem::velocityJump_Cross ( Aup0, f0, f1, intersectElements0 [ id1 ][ k ] );

			gmm::copy ( *Aup0,
						gmm::sub_matrix (*M_globalMatrix,
										gmm::sub_interval ( shiftIntersect [ id0 ], fractureNumberGlobalDOFVelocity [ id0 ] ),
										gmm::sub_interval (  fractureTotalNumberDOFVelocityPressure , 1 ) ) );

			gmm::copy ( gmm::transposed(*Aup0),
						gmm::sub_matrix (*M_globalMatrix,
										gmm::sub_interval (  fractureTotalNumberDOFVelocityPressure, 1 ),
										gmm::sub_interval ( shiftIntersect [ id0 ], fractureNumberGlobalDOFVelocity [ id0 ] ) ) );

		}

	}

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

	/*
	* 		Copy blocks into the system matrix M_darcyGlobalMatrix
	*
	* 				[  A11  A12  0          ]
	* 		    M = [ -A12  A22  0          ]
	* 		    	[  0    0    A11F  A12F ]
	* 		        [  0    0   -A12F  0    ]
	*/

	// Shift for the fracture
	size_type fractureShift = 0;
	for ( size_type f = 0; f < numberFractures; ++f )
	{
	   // Copy the matrix A11F in M_darcyGlobalMatrix in the correct position
	   gmm::copy( *( A11F [ f ] ), gmm::sub_matrix( *M_globalMatrix, gmm::sub_interval( fractureShift, fractureNumberGlobalDOFVelocity [ f ] ),
	                   										     gmm::sub_interval(fractureShift, fractureNumberGlobalDOFVelocity [ f ] )));

	   // Copy the matrix A12F in M_darcyGlobalMatrix in the correct position
	   gmm::copy( *( A12F [ f ] ), gmm::sub_matrix(*M_globalMatrix, gmm::sub_interval( fractureShift, fractureNumberGlobalDOFVelocity [ f ]),
	   														  gmm::sub_interval(fractureShift + fractureNumberGlobalDOFVelocity [ f ],
	   																  	        fractureNumberGlobalDOFPressure [ f ])));

	   // Copy the matrix -A12F in M_darcyGlobalMatrix in the correct position
	   gmm::copy(gmm::transposed(gmm::scaled(*(A12F [ f ]), -1.0)),
	   						  gmm::sub_matrix( *M_globalMatrix,
	   								  gmm::sub_interval( fractureShift + fractureNumberGlobalDOFVelocity [ f ], fractureNumberGlobalDOFPressure [ f ]),
	   								  gmm::sub_interval( fractureShift, fractureNumberGlobalDOFVelocity [ f ])));

	   // Update the shift
	   fractureShift += fractureNumberDOFVelocityPressure [ f ];

	}

	sizeVector_Type shiftVelocity ( numberFractures );
	shiftVelocity [ 0 ] = fractureNumberDOFVelocity [ 0 ];

	for ( size_type f = 0; f < numberFractures; ++f )
	{
		if( f != 0)
		{
			shiftVelocity [ f ] = shiftVelocity [ f-1 ] + M_fractures->getFracture( f-1 )->getNumExtendedVelocity() + fractureNumberGlobalDOFPressure [ f-1 ] + fractureNumberGlobalDOFVelocity [ f ];
		}

	}

    // Aggiorno ora la matrice globale imponendo le condizioni di interfaccia per la biforcazione

    for ( size_type i = 0; i < IntBifurcation.size(); i++ )
    {
    	sparseMatrixPtr_Type Aup0, Aup1, Aup2, Aup3;

    	FractureHandlerPtr_Type f0 = IntBifurcation [ i ].getFracture (0);
    	FractureHandlerPtr_Type f1 = IntBifurcation [ i ].getFracture (1);
    	FractureHandlerPtr_Type f2 = IntBifurcation [ i ].getFracture (2);

    	size_type id0 = f0->getId();
    	size_type id1 = f1->getId();
    	size_type id2 = f2->getId();

        std::cout << "Bifurcation: " << std::endl;
		std::cout << " Fractures " << id0 << ", " << id1 << ", " << id2 << std::endl;

		const size_type globalIndex = GlobalIndex_Bifurcation( M_fractures , id0,id1, id2 );
		const size_type Index = fractureTotalNumberDOFVelocityPressure + globalIndex;

        Aup0.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
        gmm::clear(*Aup0);

        Aup1.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
        gmm::clear(*Aup1);

        Aup2.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
        gmm::clear(*Aup2);

        Aup3.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
	    gmm::clear(*Aup3);

        MatrixBifurcationHandler_Type Matrix( dataFile );
		FracturePtrContainer_Type Fracture( 3 );
		Fracture[ 0 ] =f0;
		Fracture[ 1 ] =f1;
		Fracture[ 2 ] =f2;

		FracturePtrContainer_Type Fracture_copy( 3 );
		Fracture_copy = Fracture;

		Matrix.setMatrices( Fracture_copy );

		Matrix4d T = Matrix.T();

		scalar_type s = 0.;
		Matrix.computeScap ( s );

		scalarVector_Type DOF( 3 );
		scalarVector_Type DOF_v( 3 );

		DOF_v = getfem::setDOF_v( DOF, Fracture, Matrix );

		getfem::setAup_i( Aup0, 0 , id0, id1, id2, DOF, DOF_v, shiftIntersect, fractureNumberGlobalDOFVelocity,  T, Index );
		getfem::setAup_i( Aup1, 1 , id1, id0, id2, DOF, DOF_v, shiftIntersect, fractureNumberGlobalDOFVelocity,  T, Index );
		getfem::setAup_i( Aup2, 2 , id2, id0, id1, DOF, DOF_v, shiftIntersect, fractureNumberGlobalDOFVelocity,  T, Index );
		getfem::setAup_i( Aup3, 3 , id2, id0, id1, DOF, DOF_v, shiftIntersect, fractureNumberGlobalDOFVelocity,  T, Index, s );

		gmm::copy(*Aup0, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( shiftVelocity[ id0 ] + DOF[ 0 ], 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

		gmm::copy(*Aup1, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( shiftVelocity[ id1 ] + DOF[ 1 ], 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

		gmm::copy(*Aup2, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( shiftVelocity[ id2 ] + DOF[ 2 ], 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

		gmm::copy(*Aup3, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( fractureTotalNumberDOFVelocityPressure  + 2*fractureNumberCross + i, 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

    }

    // Aggiorno ora la matrice globale imponendo le condizioni di interfaccia per la biforcazione di tipo 2
    for ( size_type i = 0; i < IntBifurcation2.size(); i++ )
    {

		sparseMatrixPtr_Type Aup0, Aup1, Aup2, Aup3, Aup4;

    	FractureHandlerPtr_Type f0, f1;

		if( IntBifurcation2 [ i ].getFracture (0)->getDOFBifurcation().size() != 0 )
		{
			f0 = IntBifurcation2 [ i ].getFracture (0);
			f1 = IntBifurcation2 [ i ].getFracture (1);
		}
		else
		{
			f1 = IntBifurcation2 [ i ].getFracture (0);
			f0 = IntBifurcation2 [ i ].getFracture (1);
		}

    	size_type id0 = f0->getId();
    	size_type id1 = f1->getId();

        std::cout << "Bifurcation: " << std::endl;
		std::cout << " Fractures " << id0 << ", " << id1 << std::endl;

    	const pairSizeVectorContainer_Type& intersectElementsGlobalIndex0 = M_fractures->getFracture( id0 )->getFractureIntersectElementsGlobalIndex ();

		const size_type globalIndex01 =  intersectElementsGlobalIndex0[ id1 ][ 0 ].first;

        const pairSizeVectorContainer_Type& intersectElementsGlobalIndex1 = M_fractures->getFracture( id1 )->getFractureIntersectElementsGlobalIndex ();

		const size_type globalIndex10 =  intersectElementsGlobalIndex1[ id0 ][ 0 ].first;

		const size_type globalIndex = fmin ( globalIndex01, globalIndex10 );

		const size_type globalShift = fractureTotalNumberDOFVelocityPressure + globalIndex;

        Aup0.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
        gmm::clear(*Aup0);

        Aup1.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
        gmm::clear(*Aup1);

        Aup2.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
        gmm::clear(*Aup2);

        Aup3.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
	    gmm::clear(*Aup3);

        Aup4.reset ( new sparseMatrix_Type ( 1, fractureTotalNumberDOFVelocityPressure + globalFractureNumber) );
	    gmm::clear(*Aup4);

        MatrixBifurcationHandler_Type Matrix( dataFile, "Bifurcation2" );
		FracturePtrContainer_Type Fracture( 2 );
		Fracture[ 0 ] =f0;
		Fracture[ 1 ] =f1;

		FracturePtrContainer_Type Fracture_copy( 2 );
		Fracture_copy = Fracture;
		Matrix.setMatrices( Fracture_copy );

		Matrix4d T = Matrix.T();

		scalarVector_Type DOF_p0( 2 );
		scalarVector_Type DOF_v0( 4 );
		scalar_type DOF_p1;
		scalar_type DOF_v1;

		Matrix.SetDOFIntersecton( Fracture[ 0 ], DOF_p0[ 0 ] );
		Matrix.SetDOFIntersecton( Fracture[ 1 ], DOF_p1 );

		const size_type nbDOF =  Fracture[ 1 ]-> getMeshFEMPressure().nb_basic_dof();

		if( DOF_p1 == nbDOF - 1 )
		{
			DOF_v1 = DOF_p1 + 1.;
		}
		else
		{
			DOF_v1 = DOF_p1;
		}

		DOF_p0[ 1 ] = shiftIntersect[ id0 ] + fractureNumberDOFVelocity [ 0 ] + fractureNumberDOFPressure  [ 0 ] + Fracture[ 0 ]->getNumExtendedVelocity();
		DOF_v0[ 0 ] = DOF_p0[ 0 ];
		DOF_v0[ 1 ] = DOF_p0[ 0 ]+1;
		DOF_v0[ 2 ] = shiftIntersect[ id0 ] + fractureNumberDOFVelocity [ 0 ];
		DOF_v0[ 3 ] = shiftIntersect[ id0 ] + fractureNumberDOFVelocity [ 0 ] + 1;

		(*Aup0) ( 0 , shiftIntersect[ id0 ] + DOF_v0[ 0 ] )  = 0.5;
		(*Aup0) ( 0 , shiftIntersect[ id0 ] + DOF_v0[ 3 ] )  = 0.5;
		(*Aup0) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 0 ] + fractureNumberGlobalDOFVelocity [ id0 ] ) = 1.*T( 0 , 0 );
		(*Aup0) ( 0 , shiftIntersect[ id1 ] + DOF_p1 + fractureNumberGlobalDOFVelocity [ id1 ] ) = 1.*T( 0 , 1 );
		(*Aup0) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 1 ] ) = 1.*T( 0 , 2 );
		(*Aup0) ( 0 , globalShift + 1 ) = 1.*T( 0 , 3 );
		(*Aup0) ( 0 , globalShift ) = -1.*( T( 0 , 0 ) + T( 0 , 1 ) + T( 0 , 2 ) + T( 0 , 3 ) );

		gmm::copy(*Aup0, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( shiftVelocity[ id0 ]  + DOF_p0[ 0 ], 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

		(*Aup1) ( 0 , shiftIntersect[ id1 ] + DOF_v1 )  = 1.;
		(*Aup1) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 0 ] + fractureNumberGlobalDOFVelocity [ id0 ] ) = 1.*T( 1 , 0 );
		(*Aup1) ( 0 , shiftIntersect[ id1 ] + DOF_p1 + fractureNumberGlobalDOFVelocity [ id1 ] ) = 1.*T( 1 , 1 );
		(*Aup1) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 1 ] ) = 1.*T( 1 , 2 );
		(*Aup1) ( 0 , globalShift + 1 ) = 1.*T( 1 , 3 );
		(*Aup1) ( 0 , globalShift ) = -1.*( T( 1 , 0 ) + T( 1 , 1 ) + T( 1 , 2 ) + T( 1 , 3 ) );

		gmm::copy(*Aup1, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( shiftVelocity[ id1 ] + DOF_p1, 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

		(*Aup2) ( 0 , shiftIntersect[ id0 ] + DOF_v0[ 1 ] ) = 0.5;
		(*Aup2) ( 0 , shiftIntersect[ id0 ] + DOF_v0[ 2 ] ) = 0.5;
		(*Aup2) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 0 ] + fractureNumberGlobalDOFVelocity [ id0 ] ) = 1.*T( 2 , 0 );
		(*Aup2) ( 0 , shiftIntersect[ id1 ] + DOF_p1 + fractureNumberGlobalDOFVelocity [ id1 ] ) = 1.*T( 2 , 1 );
		(*Aup2) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 1 ] ) = 1.*T( 2 , 2 );
		(*Aup2) ( 0 , globalShift + 1 ) = 1.*T( 2 , 3 );
		(*Aup2) ( 0 , globalShift ) = -1.*( T( 2 , 0 ) + T( 2 , 1 ) + T( 2 , 2 ) + T( 2 , 3 ) );

		gmm::copy(*Aup2, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( DOF_p0[ 1 ], 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

		// Imponiamo condizione di non slip alla parete
		(*Aup3) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 0 ] + fractureNumberGlobalDOFVelocity [ id0 ] ) = 1.*T( 3 , 0 );
		(*Aup3) ( 0 , shiftIntersect[ id1 ] + DOF_p1 + fractureNumberGlobalDOFVelocity [ id1 ] ) = 1.*T( 3 , 1 );
		(*Aup3) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 1 ] ) = 1.*T( 3 , 2 );
		(*Aup3) ( 0 , globalShift + 1 ) = 1.*T( 3 , 3 );
		(*Aup3) ( 0 , globalShift ) = -1.*( T( 3 , 0 ) + T( 3 , 1 ) + T( 3 , 2 ) + T( 3 , 3 ) );

		gmm::copy(*Aup3, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( globalShift + 1 , 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

		scalar_type s = 0.;

		Matrix.computeScap ( s );

		// velocità: attenzione alla convenzione dei segni!!

		(*Aup4) ( 0 , shiftIntersect[ id0 ] + DOF_v0[ 0 ] )  = -1./( 8.0 * s );
		(*Aup4) ( 0 , shiftIntersect[ id0 ] + DOF_v0[ 3 ] )  = 1./( 8.0 * s );
		(*Aup4) ( 0 , shiftIntersect[ id0 ] + DOF_v0[ 1 ]  )  = 1./( 8.0 * s );
		(*Aup4) ( 0 , shiftIntersect[ id0 ] + DOF_v0[ 2 ]  )  = -1./( 8.0 * s );

		if ( DOF_v1 == 0 )
		{
			(*Aup4) ( 0 , shiftIntersect[ id1 ] + DOF_v1 )  = 1./( 4.0 * s );
		}
		else
		{
			(*Aup4) ( 0 , shiftIntersect[ id1 ] + DOF_v1 )  = -1./( 4.0 * s );
		}

		// pressione
		(*Aup4) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 0 ] + fractureNumberGlobalDOFVelocity [ id0 ] ) = -1./4.;
		(*Aup4) ( 0 , shiftIntersect[ id1 ] + DOF_p1 + fractureNumberGlobalDOFVelocity [ id1 ] ) = -1./4.;
		(*Aup4) ( 0 , shiftIntersect[ id0 ] + DOF_p0[ 1 ] ) = -1./4.;
		(*Aup4) ( 0 , globalShift + 1 ) = -1./4.;

		// pressione media
		(*Aup4) ( 0 , globalShift ) = 1.;

		gmm::copy(*Aup4, gmm::sub_matrix(*M_globalMatrix,
	    		gmm::sub_interval( globalShift, 1),
	    		gmm::sub_interval( 0, fractureTotalNumberDOFVelocityPressure + globalFractureNumber ) ));

    }

     gmm::copy(*App, gmm::sub_matrix(*M_globalMatrix,
    		gmm::sub_interval( fractureTotalNumberDOFVelocityPressure, fractureNumberCross ),
    		gmm::sub_interval( fractureTotalNumberDOFVelocityPressure, 2*fractureNumberCross ) ));

    //Costruiamo il termine noto

    // Vector, Neumann conditions
    scalarVectorPtrContainer_Type BstressF(numberFractures);

    // Pressure term (Neumann)
    scalarVectorPtrContainer_Type PneumannF(numberFractures);

    // Velocity term (Dirichilet)
    scalarVectorPtrContainer_Type VdirichletF(numberFractures);

    // Right Hand Side: velocity and pressure
    scalarVectorPtrContainer_Type B_vF(numberFractures);

    // Right Hand Side: velocity and pressure
    scalarVectorPtrContainer_Type B_pF(numberFractures);

    for ( size_type f = 0; f < numberFractures; ++f )
    {
        BstressF [ f ].reset(new scalarVector_Type( fractureNumberGlobalDOFVelocity [ f ], 0.));

        PneumannF [ f ].reset(new scalarVector_Type( fractureNumberBoundaryDOF [ f ], 0.));

        VdirichletF [ f ].reset(new scalarVector_Type( fractureNumberDOFPressure [ f ], 0.));

        B_vF [ f ].reset(new scalarVector_Type(fractureNumberGlobalDOFVelocity [ f ], 0.));

        B_pF [ f ].reset(new scalarVector_Type(fractureNumberGlobalDOFPressure [ f ], 0.));

    }

    for ( size_type f = 0; f < numberFractures; ++f )
    {
        const BCPtr_Type& fractureBC = M_bcHandler->getFractureBC( f );

        for ( size_type i = 0; i < fractureNumberBoundaryDOF [ f ]; i++ )
        {
            const base_node node = fractureBC->getMeshFEM().point_of_basic_dof( i );

            (*(PneumannF [ f ])) [ i ] = M_fractures->getFracture( f )->getData().pressureExact( node );
        }

        (*(PneumannF [ f ])) [ 0 ] *= -1;
    }

    for ( size_type f = 0; f < numberFractures; ++f )
    {
    	std::cout << "Fracture " << f << std::endl;

        // Computes the right hand side rhs which stores the boundary conditions for the fracture
        getfem::darcy_dataF ( BstressF [ f ], B_vF [ f ], M_bcHandler,
                              M_fractures->getFracture( f ), M_mediumData->getPenaltyVector(),
                              M_mediumData->getInvK(), PneumannF [ f ], VdirichletF [ f ] );

        std::cout<< std::endl;
    }

    fractureShift = 0;

    for ( size_type f = 0; f < numberFractures; ++f )
    {
        for ( size_type i = 0; i < fractureNumberGlobalDOFVelocity [ f ]; ++i )
        {
            (*M_globalRightHandSide) [ fractureShift + i ] += (*(BstressF [ f ])) [ i ];

            (*M_globalRightHandSide) [ fractureShift + i ] += (*(B_vF [ f ])) [ i ];
        }

        // Update the shift
        fractureShift += fractureNumberDOFVelocityPressure [ f ];
    }

    scalarVectorPtrContainer_Type divF(numberFractures);

    fractureShift = 0;

    for ( size_type f = 0; f < numberFractures; ++f )
    {
        divF [ f ].reset(new scalarVector_Type(fractureNumberDOFPressure [ f ], 0.));

        for ( size_type i = 0; i < fractureNumberDOFPressure [ f ]; i++ )
        {
            const base_node node = M_fractures->getFracture( f )->getMeshFEMPressure().point_of_basic_dof( i );

            (*(divF [ f ])) [ i ] = M_fractures->getFracture( f )->getData().darcySource( node );
        }

        gmm::clear(*(B_pF [ f ]));

        getfem::assembling_Source_BoundaryF ( B_pF [ f ], divF [ f ], M_fractures->getFracture( f ), FractureHandler::FRACTURE_UNCUT * ( f + 1 ) );

    }

    // Aggiorno prima le matrici di tutte le fratture che si intersecano formando un " Cross "
    for ( size_type i = 0; i < IntCross.size(); i++ )
    {
    	FractureHandlerPtr_Type f0 = IntCross [ i ].getFracture (0);
    	FractureHandlerPtr_Type f1 = IntCross [ i ].getFracture (1);

    	size_type id0 = f0->getId();
    	size_type id1 = f1->getId();

    	getfem::assembling_SourceF ( B_pF [ id0 ], divF [ id0 ],
    								f0, f1, FractureHandler::FRACTURE_INTERSECT * ( id0 + 1 ) + id1 + 1 );

    	getfem::assembling_SourceF ( B_pF [ id1 ], divF [ id1 ],
    								f1, f0, FractureHandler::FRACTURE_INTERSECT * ( id1 + 1 ) + id0 + 1 );

    }

    // Aggiorno le matrici di tutte le fratture che si intersecano formando un " IntBifurcation2 "

    for ( size_type i = 0; i < IntBifurcation2.size(); i++ )
    {
    	FractureHandlerPtr_Type f0 = IntBifurcation2 [ i ].getFracture (0);
    	FractureHandlerPtr_Type f1 = IntBifurcation2 [ i ].getFracture (1);

    	size_type id0 = f0->getId();
    	size_type id1 = f1->getId();

    	getfem::assembling_SourceF ( B_pF [ id0 ], divF [ id0 ],
    								f0, f1, FractureHandler::FRACTURE_INTERSECT * ( id0 + 1 ) + id1 + 1 );

    }

    fractureShift = 0;

    for ( size_type f = 0; f < numberFractures; ++f )
    {

        for ( size_type i = fractureNumberGlobalDOFVelocity [ f ]; i < fractureNumberDOFVelocityPressure [ f ]; ++i )
        {
                (*M_globalRightHandSide) [ fractureShift + i ] += (*(B_pF [ f ])) [ i - fractureNumberGlobalDOFVelocity [ f ] ];
        }

        // Update the shift
        fractureShift += fractureNumberDOFVelocityPressure [ f ];

    }

    // Curo la matrice
    for ( size_type i = 0; i < M_globalRightHandSide->size(); ++i )
    {
        scalar_type somma = 0;

        for ( size_type j = 0; j < M_globalRightHandSide->size(); ++j )
        {
            somma += std::fabs( (*M_globalMatrix) (i, j) );
        }

        if ( somma == 0 )
        {
            (*M_globalRightHandSide) [ i ] = 0.;
            (*M_globalMatrix) (i, i) = 1.;
        }
    }

    M_exporter->spy(M_globalMatrix, "./Matlab/matrice.mm");
    M_exporter->spy(M_globalRightHandSide, "./Matlab/rhs.mm");

    return;

}// assembly

// Solve the Darcy for the governing flux and do the time loop for the evolution problem
void DarcyFractured::solve ( )
{
	// numero totale delle fratture
	const scalar_type numberFractures = M_fractures->getNumberFractures();

	// vettore dei gradi di libertà per la velocità per le fratture
    sizeVector_Type fractureNumberDOFVelocity(numberFractures);

    // numero di gradi di libertà totali per la velocità (con quelli estesi) per ogni frattura
    sizeVector_Type fractureNumberGlobalDOFVelocity(numberFractures);

    // vettore dei gradi di libertà per la pressione per le fratture
    sizeVector_Type fractureNumberDOFPressure(numberFractures);

    // numero di gradi di libertà totali per la pressione (con quelli estesi) per ogni frattura
    sizeVector_Type fractureNumberGlobalDOFPressure(numberFractures);

    // numero totale dei gradi di libertà ( velocità + pressione ) per ogni frattura
    sizeVector_Type fractureNumberDOFVelocityPressure(numberFractures);

    // numero complessivo dei gradi di libertà ( pressione + velocità )
    size_type fractureTotalNumberDOFVelocityPressure(0);

    for ( size_type f = 0; f < numberFractures; ++f )
    {
    	// numero di gradi di libertà per la velocità senza quelli estesi per la frattura f
        fractureNumberDOFVelocity [ f ] = M_fractures->getFracture( f )->getMeshFEMVelocity().nb_dof();

        // numero di gradi di libertà per la velocità con quelli estesi per la frattura f
        fractureNumberGlobalDOFVelocity [ f ] = fractureNumberDOFVelocity [ f ] + M_fractures->getFracture( f )->getNumExtendedVelocity();

        // numero di gradi di libertà per la pressione senza quelli estesi per la frattura f
        fractureNumberDOFPressure [ f ] = M_fractures->getFracture( f )->getMeshFEMPressure().nb_dof();

        // numero di gradi di libertà per la pressione con quelli estesi per la frattura f
        fractureNumberGlobalDOFPressure [ f ] = fractureNumberDOFPressure [ f ] + M_fractures->getFracture( f )->getNumExtendedPressure();

        // numero totale di gradi di libertà per la velocità e la pressione per la frattura f
        fractureNumberDOFVelocityPressure [ f ] = fractureNumberGlobalDOFVelocity [ f ] + fractureNumberGlobalDOFPressure [ f ];

        // numero totale di gradi di libertà per la pressione e la velocità
        fractureTotalNumberDOFVelocityPressure += fractureNumberDOFVelocityPressure [ f ];

        M_fracturePressure [ f ].reset(new scalarVector_Type( fractureNumberGlobalDOFPressure [ f ], 0));

        M_fractureVelocity [ f ].reset(new scalarVector_Type( fractureNumberGlobalDOFVelocity [ f ], 0));

    }

    // Solve the Darcy problem
    std::cout << std::endl << "Solving problem in Omega..." << std::flush;
    scalar_type roundConditionNumber;

    SuperLU_solve(*M_globalMatrix, *M_velocityAndPressure,
                  *M_globalRightHandSide, roundConditionNumber);

    size_type fractureShift = 0;

    for ( size_type f = 0; f < numberFractures; ++f )
    {
        // Extract the dual in the fracture
        gmm::copy( gmm::sub_vector( *M_velocityAndPressure, gmm::sub_interval( fractureShift, fractureNumberGlobalDOFVelocity [ f ])),
                  *( M_fractureVelocity [ f ] ) );

        // Extract the primal in the fracture
        gmm::copy( gmm::sub_vector( *M_velocityAndPressure,
        							gmm::sub_interval( fractureShift + fractureNumberGlobalDOFVelocity [ f ], fractureNumberGlobalDOFPressure [ f ])),
        		   *(M_fracturePressure [ f ]));

        // Update the shift
        fractureShift += fractureNumberDOFVelocityPressure [ f ];
    }

    // the extra dof start at the end of the fracture dofs

    getfem::pfem fractureFETypePressure;
    getfem::pfem fractureFETypeVelocity;

    if ( numberFractures > 0 )
    {
        fractureFETypePressure = getfem::fem_descriptor( M_fractures->getFracture( 0 )->getData().getFEMTypePressure());
        fractureFETypeVelocity = getfem::fem_descriptor( M_fractures->getFracture( 0 )->getData().getFEMTypeVelocity());
    }

    //--------export solution in the fracture-------------------
    for ( size_type f = 0; f < numberFractures; ++f )
    {
        FractureHandlerPtr_Type& fracture = M_fractures->getFracture(f);
        std::ostringstream osFileName;

        getfem::mesh_level_set meshFLevelSetCutFlat ( fracture->getMeshFlat() );
        for ( size_type otherF = 0; otherF < numberFractures; ++otherF )
        {
            GFLevelSetPtr_Type levelSetPtr = fracture->getLevelSetIntersect ( otherF );

            if ( levelSetPtr.get() != NULL )
            {
                meshFLevelSetCutFlat.add_level_set ( *levelSetPtr );
            }
        }

        meshFLevelSetCutFlat.adapt();

        getfem::mesh meshFcutFlat;
        getfem::mesh meshFcutMapped;
        meshFLevelSetCutFlat.global_cut_mesh ( meshFcutFlat );

        getfem::mesh_fem meshFEMcutFlat ( meshFcutFlat, fracture->getMeshFEMPressure().get_qdim());
        meshFEMcutFlat.set_finite_element ( fracture->getMeshFEMVelocity().fem_of_element(0) );

        scalarVector_Type ordinataUncut ( fractureNumberDOFVelocity [ f ], 0. );
        scalarVector_Type ordinataCut ( meshFEMcutFlat.nb_dof(), 0. );

        for ( size_type i = 0; i < fractureNumberDOFVelocity [ f ]; ++i )
        {
            const bgeot::base_node P = fracture->getMeshFEMVelocity().point_of_basic_dof(i);

            bgeot::base_node P1 = fracture->getMeshMapped().points( ) [i];

            scalar_type c= 1./fracture->getData().getSpatialDiscretization ();

            P1 [0] =  i*c;

            ordinataUncut [ i ] = fracture->getLevelSet()->getData()->y_map(P1);
        }

        getfem::interpolation ( fracture->getMeshFEMVelocity(), meshFEMcutFlat, ordinataUncut, ordinataCut );

        for ( size_type i = 0; i < meshFEMcutFlat.nb_dof(); ++i )
        {
            bgeot::base_node P ( fracture->getData().getSpaceDimension() + 2 );

            P [ 0 ] = meshFEMcutFlat.point_of_basic_dof(i)[0];
            P [ 1 ] = ordinataCut [ i ];

            meshFcutMapped.add_point(P);
        }

        const size_type numConvex = meshFcutFlat.convex_index().size();

        for ( size_type i = 0; i < numConvex; ++i )
        {
            std::vector<bgeot::size_type> point(3);

            point [ 0 ] = meshFcutFlat.ind_points_of_convex(i) [ 0 ];
            point [ 1 ] = meshFcutFlat.ind_points_of_convex(i) [ 1 ];
            point [ 2 ] = meshFcutFlat.ind_points_of_convex(i) [ 2 ];

            meshFcutMapped.add_convex( fracture->getGeometricTransformation(), point.begin() );
        }

        // per ogni frattura esporto la mesh reale
        osFileName << "cmeshF2-" << f << ".vtk";
        exportMesh(M_exporter->getFolder() + osFileName.str().c_str(), meshFcutMapped );

        getfem::mesh_fem mfproj ( meshFcutMapped, fracture->getMeshFEMPressure().get_qdim() );
        getfem::mesh_fem mfproj_v ( meshFcutMapped, fracture->getMeshFEMVelocity().get_qdim() );

        mfproj.set_classical_discontinuous_finite_element ( 0, 0.01 );
        mfproj_v.set_classical_discontinuous_finite_element ( 0, 0.01 );

        scalarVector_Type fracturePressureMeanUNCUT ( fractureNumberDOFPressure [ f ], 0. );
        scalarVector_Type fracturePressureInCut ( fractureNumberDOFPressure [ f ], 0. );
        scalarVector_Type fracturePressureOutCut ( fractureNumberDOFPressure [ f ], 0. );

        scalarVector_Type fractureVelocityMeanUNCUT ( fractureNumberDOFVelocity [ f ], 0. );
        scalarVector_Type fractureVelocityInCut ( fractureNumberDOFVelocity [ f ], 0. );
        scalarVector_Type fractureVelocityOutCut ( fractureNumberDOFVelocity [ f ], 0. );

        for ( size_type i = 0; i < fractureNumberDOFPressure [ f ]; ++i )
        {
            const size_type el =  fracture->getMeshFEMPressure().first_convex_of_basic_dof(i);

            if ( fracture->getMeshFlat().region ( FractureHandler::FRACTURE_UNCUT * ( f + 1 ) ).is_in(el) )
            {
                fracturePressureMeanUNCUT [ i ] = (*(M_fracturePressure [ f ])) [ i ];
            }
         }

        for ( size_type i = 0; i < fractureNumberDOFVelocity [ f ]; ++i )
        {
            const size_type el =  fracture->getMeshFEMVelocity().first_convex_of_basic_dof(i);

            if ( fracture->getMeshFlat().region ( FractureHandler::FRACTURE_UNCUT * ( f + 1 ) ).is_in(el) )
            {
                fractureVelocityMeanUNCUT [ i ] = (*(M_fractureVelocity [ f ])) [ i ];
            }
        }

        /*
         * getfem risolve il sistema per la mesh " piatta ", per avere i corretti valori di pressione devo interpolare
         * sulla mesh mappata i valori che ho ottenuto
         *
         */
        scalarVector_Type fracturePressureMeanUNCUTInterpolated ( mfproj.nb_dof(), 0. );
        scalarVector_Type fracturePressureMeanInCutInterpolated ( mfproj.nb_dof(), 0. );
        scalarVector_Type fracturePressureMeanOutCutInterpolated ( mfproj.nb_dof(), 0. );

        scalarVector_Type fractureVelocityMeanUNCUTInterpolated ( mfproj_v.nb_dof(), 0. );
        scalarVector_Type fractureVelocityMeanInCutInterpolated ( mfproj_v.nb_dof(), 0. );
        scalarVector_Type fractureVelocityMeanOutCutInterpolated ( mfproj_v.nb_dof(), 0. );

        getfem::mesh_fem mfprojUncut ( fracture->getMeshMapped(), fracture->getMeshFEMPressure().get_qdim());
        mfprojUncut.set_finite_element ( fractureFETypePressure );

        getfem::mesh_fem mfprojUncut_v ( fracture->getMeshMapped(), fracture->getMeshFEMVelocity().get_qdim());
        mfprojUncut_v.set_finite_element ( fractureFETypeVelocity );

        getfem::interpolation ( mfprojUncut, mfproj, fracturePressureMeanUNCUT, fracturePressureMeanUNCUTInterpolated );

        getfem::interpolation ( mfprojUncut_v, mfproj_v, fractureVelocityMeanUNCUT, fractureVelocityMeanUNCUTInterpolated );

        const sizeVector_Type& extendedPressure = fracture->getExtendedPressure();

        const sizeVector_Type& extendedVelocity = fracture->getExtendedVelocity();

        for ( size_type otherFracture = 0; otherFracture < numberFractures; ++otherFracture )
        {
            if ( fracture->getLevelSetIntersect( otherFracture ).get() )
            {
                getfem::mesh_region regionMesh = fracture->getMeshFlat().region ( FractureHandler::FRACTURE_INTERSECT * ( f + 1 ) + otherFracture + 1 );
                size_type i_cv = 0;
                dal::bit_vector bc_cv = regionMesh.index();
                gmm::clear ( fracturePressureInCut );
                gmm::clear ( fracturePressureOutCut );

                for ( i_cv << bc_cv; i_cv != size_type(-1); i_cv << bc_cv )
                {
                    const size_type ibase = fracture->getMeshFEMPressure().ind_basic_dof_of_element ( i_cv )[0];
                    const size_type position = size_type ( std::find ( extendedPressure.begin(), extendedPressure.end(), ibase )
                                                - extendedPressure.begin());

                    const base_node point = mfprojUncut.point_of_basic_dof ( ibase );
                    const scalar_type levelSetValue = M_fractures->getFracture( otherFracture )->getLevelSet()->getData()->levelSetFunction( point );

                    if ( levelSetValue < 0 )
                    {
                        fracturePressureInCut [ ibase ] = (*(M_fracturePressure [ f ])) [ ibase ];
                        fracturePressureOutCut [ ibase ] = (*(M_fracturePressure [ f ])) [ fractureNumberDOFPressure [ f ] + position ];
                    }
                    else
                    {
                        fracturePressureOutCut [ ibase ] = (*(M_fracturePressure [ f ])) [ ibase ];
                        fracturePressureInCut [ ibase ] = (*(M_fracturePressure [ f ])) [ fractureNumberDOFPressure [ f ] + position ];
                    }

                }

                gmm::clear ( fracturePressureMeanInCutInterpolated );

                getfem::interpolation ( mfprojUncut, mfproj,
                                        fracturePressureInCut, fracturePressureMeanInCutInterpolated );

                gmm::clear ( fracturePressureMeanOutCutInterpolated );

                getfem::interpolation ( mfprojUncut, mfproj,
                                        fracturePressureOutCut, fracturePressureMeanOutCutInterpolated );

                i_cv = 0;
                bc_cv = meshFcutMapped.convex_index();
                for ( i_cv << bc_cv; i_cv != size_type(-1); i_cv << bc_cv )
                {
                    getfem::mesh_fem::ind_dof_ct idofs = mfproj.ind_basic_dof_of_element ( i_cv );
                    for ( size_type k = 0; k < idofs.size(); ++k )
                    {
                        const base_node node = mfproj.point_of_basic_dof(idofs [ k ]);
                        const scalar_type levelSetValue = M_fractures->getFracture( otherFracture )->getLevelSet()->getData()->levelSetFunction( node );
                        if ( levelSetValue < 0 )
                        {
                            fracturePressureMeanUNCUTInterpolated [ idofs[k] ] += fracturePressureMeanInCutInterpolated [ idofs[k] ];
                        }
                        else
                        {
                            fracturePressureMeanUNCUTInterpolated [ idofs[k] ] += fracturePressureMeanOutCutInterpolated [ idofs[k] ];
                        }

                    }

                }

            }
        }

        for ( size_type otherFracture = 0; otherFracture < numberFractures; ++otherFracture )
        {
            if ( fracture->getLevelSetIntersect( otherFracture ).get() )
            {
                getfem::mesh_region regionMesh = fracture->getMeshFlat().region ( FractureHandler::FRACTURE_INTERSECT * ( f + 1 ) + otherFracture + 1 );
                size_type i_cv = 0;
                dal::bit_vector bc_cv = regionMesh.index();
                gmm::clear ( fractureVelocityInCut );
                gmm::clear ( fractureVelocityOutCut );

                for ( i_cv << bc_cv; i_cv != size_type(-1); i_cv << bc_cv )
                {
                    const size_type ibase = fracture->getMeshFEMVelocity().ind_basic_dof_of_element ( i_cv )[0];
                    const size_type position = size_type ( std::find ( extendedVelocity.begin(), extendedVelocity.end(), ibase )
                                                - extendedVelocity.begin());

                    const base_node point = mfprojUncut_v.point_of_basic_dof ( ibase );
                    const scalar_type levelSetValue = M_fractures->getFracture( otherFracture )->getLevelSet()->getData()->levelSetFunction( point );

                    if ( levelSetValue < 0 )
                    {
                        fractureVelocityInCut [ ibase ] = (*(M_fractureVelocity [ f ])) [ ibase ];
                        fractureVelocityOutCut [ ibase ] = (*(M_fractureVelocity [ f ])) [ fractureNumberDOFVelocity [ f ] + position ];
                    }
                    else
                    {
                        fractureVelocityOutCut [ ibase ] = (*(M_fractureVelocity [ f ])) [ ibase ];
                        fractureVelocityInCut [ ibase ] = (*(M_fractureVelocity [ f ])) [ fractureNumberDOFVelocity [ f ] + position ];
                    }

                }

                gmm::clear ( fractureVelocityMeanInCutInterpolated );

                getfem::interpolation ( mfprojUncut_v, mfproj_v,
                                        fractureVelocityInCut, fractureVelocityMeanInCutInterpolated );

                gmm::clear ( fractureVelocityMeanOutCutInterpolated );

                getfem::interpolation ( mfprojUncut_v, mfproj_v,
                                        fractureVelocityOutCut, fractureVelocityMeanOutCutInterpolated );

                i_cv = 0;
                bc_cv = meshFcutMapped.convex_index();
                for ( i_cv << bc_cv; i_cv != size_type(-1); i_cv << bc_cv )
                {
                    getfem::mesh_fem::ind_dof_ct idofs = mfproj_v.ind_basic_dof_of_element ( i_cv );
                    for ( size_type k = 0; k < idofs.size(); ++k )
                    {
                        const base_node node = mfproj_v.point_of_basic_dof(idofs [ k ]);
                        const scalar_type levelSetValue = M_fractures->getFracture( otherFracture )->getLevelSet()->getData()->levelSetFunction( node );
                        if ( levelSetValue < 0 )
                        {
                            fractureVelocityMeanUNCUTInterpolated [ idofs[k] ] += fractureVelocityMeanInCutInterpolated [ idofs[k] ];
                        }
                        else
                        {
                            fractureVelocityMeanUNCUTInterpolated [ idofs[k] ] += fractureVelocityMeanOutCutInterpolated [ idofs[k] ];
                        }

                    }

                }

            }
        }

		std::cout<<std::endl;
		std::cout<<std::endl;
		std::cout << "Frattura " << f <<" Pressione " << fracturePressureMeanUNCUTInterpolated << std::endl;
		std::cout<<std::endl;

		if( M_fractures->getFracture( f )->getDofIntersection().size() != 0 )
		{
			std::cout << "Frattura " << f <<" Pressione nel punto di intersezione: " << fracturePressureMeanUNCUTInterpolated[ M_fractures->getFracture( f )->getDofIntersection()[ 0 ] ] << std::endl;
			std::cout << " DOF =  " << M_fractures->getFracture( f )->getDofIntersection()[ 0 ] <<std::endl;
			if( M_fractures->getFracture( f )->getDofIntersection().size()==2 )
			{
				std::cout << "Frattura " << f <<" Pressione nel punto di intersezione: " << fracturePressureMeanUNCUTInterpolated[ M_fractures->getFracture( f )->getDofIntersection()[ 1 ] ] << std::endl;
				std::cout << " DOF =  " << M_fractures->getFracture( f )->getDofIntersection()[ 1 ] <<std::endl;
			}
		}

        osFileName.str("");
        osFileName << "fracturePressure" << f << ".vtk";

        exportSolution ( M_exporter->getFolder() + osFileName.str(), "Pressure",
                     mfproj, fracturePressureMeanUNCUTInterpolated );

        osFileName.str("");
        osFileName << "fractureVelocity" << f << ".vtk";

        exportSolution ( M_exporter->getFolder() + osFileName.str(), "Velocity",
                     mfproj_v, fractureVelocityMeanUNCUTInterpolated );

    }

    return;

}


text:
package com.zupcat.service;

import com.zupcat.dao.DAO;

/**
 * Entry point for service access
 */
public interface SimpleDatastoreService {

    void setDatastoreCallsLogging(final boolean activate);

    boolean isDatastoreCallsLoggingActivated();

    void registerDAO(final DAO dao);

    <T> T getDAO(final Class<T> daoClass);

    DAO getDAO(final String entityName);
}

redpajama_set_name: RedPajamaGithub


text:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Erros extends CI_Controller{
    public function __construct() {
        parent::__construct();
    }
   public function page404() {
      //   $this->load->view('admin/template/header');
        $this->load->view("errors/html/error_404.php");
    }
}


text:
package at.ac.tuwien.dsg.mela.dataservice.dataSource.impl.queuebased.helpers.dataobjects;

import at.ac.tuwien.dsg.mela.common.jaxbEntities.monitoringConcepts.CollectedMetricValue;
import java.io.Serializable;
import javax.xml.bind.annotation.*;

/**
 * Author: Daniel Moldovan E-Mail: d.moldovan@dsg.tuwien.ac.at *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "SerializableCollectedMetricValue")
public class NumericalCollectedMetricValue implements Serializable {

    @XmlAttribute(name = "Name", required = true)
    private String name;

    @XmlAttribute(name = "Value", required = true)
    private Double value;

    @XmlAttribute(name = "Type", required = true)
    private String type;

    @XmlAttribute(name = "Units")
    private String units;

    @XmlAttribute(name = "MonitoredElementLevel")
    private String monitoredElementLevel;

    @XmlAttribute(name = "MonitoredElementID")
    private String monitoredElementID;

    @XmlAttribute(name = "TimeSinceCollection")
    //in seconds
    private long timeSinceCollection;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMonitoredElementLevel() {
        return monitoredElementLevel;
    }

    public void setMonitoredElementLevel(String monitoredElementLevel) {
        this.monitoredElementLevel = monitoredElementLevel;
    }

    public String getMonitoredElementID() {
        return monitoredElementID;
    }

    public void setMonitoredElementID(String monitoredElementID) {
        this.monitoredElementID = monitoredElementID;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getUnits() {
        return units;
    }

    public void setUnits(String units) {
        this.units = units;
    }

    public long getTimeSinceCollection() {
        return timeSinceCollection;
    }

    public void setTimeSinceCollection(long timeSinceCollection) {
        this.timeSinceCollection = timeSinceCollection;
    }

    public Double getValue() {
        return value;
    }

    public void setValue(Double value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "SerializableCollectedMetricValue{"
                + "name='" + name + '\''
                + ", value='" + value + '\''
                + ", type='" + type + '\''
                + ", units='" + units + '\''
                + ", MonitoredElementLevel='" + monitoredElementLevel + '\''
                + ", MonitoredElementID='" + monitoredElementID + '\''
                + "}";
    }

    public NumericalCollectedMetricValue withName(final String name) {
        this.name = name;
        return this;
    }

    public NumericalCollectedMetricValue withType(final String type) {
        this.type = type;
        return this;
    }

    public NumericalCollectedMetricValue withUnits(final String units) {
        this.units = units;
        return this;
    }

    public NumericalCollectedMetricValue withMonitoredElementLevel(final String monitoredElementLevel) {
        this.monitoredElementLevel = monitoredElementLevel;
        return this;
    }

    public NumericalCollectedMetricValue withMonitoredElementID(final String monitoredElementID) {
        this.monitoredElementID = monitoredElementID;
        return this;
    }

    public boolean hasMonitoredElementID() {
        return monitoredElementID != null && monitoredElementID.length() > 0;
    }

    public boolean hasMonitoredElementLevel() {
        return monitoredElementLevel != null && monitoredElementLevel.length() > 0;
    }

    public NumericalCollectedMetricValue withValue(final Double value) {
        this.value = value;
        return this;
    }

    public NumericalCollectedMetricValue withTimeSinceCollection(final long timeSinceCollection) {
        this.timeSinceCollection = timeSinceCollection;
        return this;
    }

    public static NumericalCollectedMetricValue from(CollectedMetricValue cmv) {

        NumericalCollectedMetricValue value = new NumericalCollectedMetricValue();
        value.monitoredElementLevel = cmv.getMonitoredElementLevel();
        value.monitoredElementID = cmv.getMonitoredElementID();
        value.name = cmv.getName();
        value.type = cmv.getType();
        value.units = cmv.getUnits();
        value.timeSinceCollection = Long.parseLong(cmv.getTimeSinceCollection());

        //eat the exception, if the converted value is not long, is null
        try {
            value.value = ((Number) cmv.getConvertedValue()).doubleValue();
        } catch (Exception e) {
            return null;
        }

        return value;
    }

    public CollectedMetricValue toCollectedMetricValue() {

        CollectedMetricValue collectedMetricValue = new CollectedMetricValue()
                .withMonitoredElementLevel(this.getMonitoredElementLevel())
                .withMonitoredElementID(this.getMonitoredElementID())
                .withName(this.getName())
                .withType(this.getType())
                .withUnits(this.getUnits())
                .withTimeSinceCollection("" + this.getTimeSinceCollection())
                .withValue(this.getValue().toString());

        return collectedMetricValue;
    }

}


text:
package com.amazonaws.services.ecs.model.transform;

import javax.annotation.Generated;

import com.amazonaws.SdkClientException;
import com.amazonaws.services.ecs.model.*;

import com.amazonaws.protocol.*;
import com.amazonaws.annotation.SdkInternalApi;

/**
 * InferenceAcceleratorMarshaller
 */
@Generated("com.amazonaws:aws-java-sdk-code-generator")
@SdkInternalApi
public class InferenceAcceleratorMarshaller {

    private static final MarshallingInfo<String> DEVICENAME_BINDING = MarshallingInfo.builder(MarshallingType.STRING)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("deviceName").build();
    private static final MarshallingInfo<String> DEVICETYPE_BINDING = MarshallingInfo.builder(MarshallingType.STRING)
            .marshallLocation(MarshallLocation.PAYLOAD).marshallLocationName("deviceType").build();

    private static final InferenceAcceleratorMarshaller instance = new InferenceAcceleratorMarshaller();

    public static InferenceAcceleratorMarshaller getInstance() {
        return instance;
    }

    /**
     * Marshall the given parameter object.
     */
    public void marshall(InferenceAccelerator inferenceAccelerator, ProtocolMarshaller protocolMarshaller) {

        if (inferenceAccelerator == null) {
            throw new SdkClientException("Invalid argument passed to marshall(...)");
        }

        try {
            protocolMarshaller.marshall(inferenceAccelerator.getDeviceName(), DEVICENAME_BINDING);
            protocolMarshaller.marshall(inferenceAccelerator.getDeviceType(), DEVICETYPE_BINDING);
        } catch (Exception e) {
            throw new SdkClientException("Unable to marshall request to JSON: " + e.getMessage(), e);
        }
    }

}


text:
"""Classes implementing baseline encoders for evaluation on MultiNLI.

This file holds classes implementing baselines such as Random, Average
Word Embeddings for encoding sentences to vector representations. These
are meant mainly as a test for the eval_multinli.py module.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np

class RandomEncoder(object):
  """Returns a random vector for each input sentence."""

  def __init__(self, dim, mean=0., stddev=1.):
    """Create a random encoder.

    Args:
      dim: Dimensionality of encoded vectors.
      mean: Mean of the generating normal distribution along each dimension.
      stddev: Standard deviation of the generating normal distribution along
        each dimension.
    """
    self.dim = dim
    self.normal_mean = mean
    self.normal_std = stddev

  def encode(self, text_data):
    """Encodes the input sentences to random vectors.

    Args:
      text_data: list of strings

    Returns:
      vectors: A list of numpy arrays corresponding to the
        encodings of sentences in 'data'.
    """
    return [np.random.normal(loc=self.normal_mean,
                             scale=self.normal_std,
                             size=(self.dim,))
            for _ in range(len(text_data))]


text:
package com.pgmacdesign.pgmactips.stackmanagement;

import com.pgmacdesign.pgmactips.utilities.L;
import com.pgmacdesign.pgmactips.utilities.MiscUtilities;
import com.pgmacdesign.pgmactips.utilities.StringUtilities;

import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import androidx.annotation.NonNull;

/**
 * This class is used for managing multiple stacks. An example would be if one needed to maintain
 * stacks of fragments for various 'paths' in an app and need to persist a managed list of
 * each of them.
 *
 * This variation is designed to use raw types; specifically: String, Integer, Long, Double
 *
 */
public class StackRawManager {

	private static enum StackType {
		TypeString, TypeInteger, TypeLong, TypeDouble, TypeGenericObject;
	}

	//region Static Vars
	private static final String BAD_STRING = "The string you passed was null or empty, please check your params and try again";
	private static final String INSTANTIATION_ERROR = "No stack was created; please check your params and re-instantiate the object";
	private static final String INVALID_KEY = "The key (int) you passed did not return a managed stack. Please check your key (See the ones sent in the constructor)";
	private static final String NO_NEGATIVE_NUMBERS_TO_POP = "Number of items to pop off the stack is <0. Number must be >0";
	private static final String INITIAL_VALUE_EMPTY= "Initial value be empty or null!";
	private static final String INITIAL_MAP_EMPTY = "Initial map cannot be empty or null!";
	private static final String INITIAL_MAP_KEYS_EMPTY = "Initial map keys be empty or null!";
	private static final String INITIAL_MAP_VALUES_EMPTY = "Initial map values be empty or null!";
	//endregion

	//region Instance Vars
	private StackType stackType;
	private Map<Integer, CustomStackManagerPOJO> managedStacks;
	private boolean maintainMinimumOneItemInStack, logChangesInStacks,
			allowStackDuplicates, shouldIgnoreStringCase;
	//endregion

	//region Builder

	/**
	 * Builder Class
	 */
	public static final class Builder {

		Map<Integer, String> initialStacksString;
		Map<Integer, Integer> initialStacksInteger;
		Map<Integer, Long> initialStacksLong;
		Map<Integer, Double> initialStacksDouble;
		Map<Integer, Object> initialStacksGenericObject;
		boolean maintainMinimumOneItemInStack;
		boolean logChangesInStacks;
		boolean allowStackDuplicates;
		boolean shouldIgnoreStringCase;
		StackType localStackType;

		/**
		 * Shortcut version to create a stack manager with 1 managed stack where the
		 * tag to reference it is always 0 (zero).
		 * @param firstOneInStack First item to put into stack zero
		 */
		public Builder(@NonNull String firstOneInStack) throws IllegalArgumentException {
			if(StringUtilities.isNullOrEmpty(firstOneInStack)){
				throw new IllegalArgumentException(INITIAL_VALUE_EMPTY);
			}
			Map<Integer, String> firstValues = new HashMap<>();
			firstValues.put(0, firstOneInStack);
			if(MiscUtilities.isMapNullOrEmpty(firstValues)){
				throw new IllegalArgumentException(INITIAL_MAP_EMPTY);
			}
			for(Map.Entry<Integer, String> map : firstValues.entrySet()){
				if(map.getKey() == null){
					throw new IllegalArgumentException(INITIAL_MAP_KEYS_EMPTY);
				}
				if(StringUtilities.isNullOrEmpty(map.getValue())){
					throw new IllegalArgumentException(INITIAL_MAP_VALUES_EMPTY);
				}
			}
			this.initialStacksString = firstValues;
			this.logChangesInStacks = false;
			this.shouldIgnoreStringCase = false;
			this.allowStackDuplicates = false;
			this.maintainMinimumOneItemInStack = true;
			this.localStackType = StackType.TypeString;
		}

		/**
		 * Shortcut version to create a stack manager with 1 managed stack where the
		 * tag to reference it is always 0 (zero).
		 * @param firstOneInStack First item to put into stack zero
		 */
		public Builder(@NonNull Integer firstOneInStack) throws IllegalArgumentException {
			if(StringUtilities.isNullOrEmpty(firstOneInStack)){
				throw new IllegalArgumentException(INITIAL_VALUE_EMPTY);
			}
			Map<Integer, Integer> firstValues = new HashMap<>();
			firstValues.put(0, firstOneInStack);
			if(MiscUtilities.isMapNullOrEmpty(firstValues)){
				throw new IllegalArgumentException(INITIAL_MAP_EMPTY);
			}
			for(Map.Entry<Integer, Integer> map : firstValues.entrySet()){
				if(map.getKey() == null){
					throw new IllegalArgumentException(INITIAL_MAP_KEYS_EMPTY);
				}
				if(map.getValue() == null){
					throw new IllegalArgumentException(INITIAL_MAP_VALUES_EMPTY);
				}
			}
			this.initialStacksInteger = firstValues;
			this.logChangesInStacks = false;
			this.shouldIgnoreStringCase = false;
			this.allowStackDuplicates = false;
			this.maintainMinimumOneItemInStack = true;
			this.localStackType = StackType.TypeInteger;
		}

		/**
		 * Shortcut version to create a stack manager with 1 managed stack where the
		 * tag to reference it is always 0 (zero).
		 * @param firstOneInStack First item to put into stack zero
		 */
		public Builder(@NonNull Long firstOneInStack) throws IllegalArgumentException {
			if(StringUtilities.isNullOrEmpty(firstOneInStack)){
				throw new IllegalArgumentException(INITIAL_VALUE_EMPTY);
			}
			Map<Integer, Long> firstValues = new HashMap<>();
			firstValues.put(0, firstOneInStack);
			if(MiscUtilities.isMapNullOrEmpty(firstValues)){
				throw new IllegalArgumentException(INITIAL_MAP_EMPTY);
			}
			for(Map.Entry<Integer, Long> map : firstValues.entrySet()){
				if(map.getKey() == null){
					throw new IllegalArgumentException(INITIAL_MAP_KEYS_EMPTY);
				}
				if(map.getValue() == null){
					throw new IllegalArgumentException(INITIAL_MAP_VALUES_EMPTY);
				}
			}
			this.initialStacksLong = firstValues;
			this.logChangesInStacks = false;
			this.shouldIgnoreStringCase = false;
			this.allowStackDuplicates = false;
			this.maintainMinimumOneItemInStack = true;
			this.localStackType = StackType.TypeLong;
		}

		/**
		 * Shortcut version to create a stack manager with 1 managed stack where the
		 * tag to reference it is always 0 (zero).
		 * @param firstOneInStack First item to put into stack zero
		 */
		public Builder(@NonNull Double firstOneInStack) throws IllegalArgumentException {
			if(StringUtilities.isNullOrEmpty(firstOneInStack)){
				throw new IllegalArgumentException(INITIAL_VALUE_EMPTY);
			}
			Map<Integer, Double> firstValues = new HashMap<>();
			firstValues.put(0, firstOneInStack);
			if(MiscUtilities.isMapNullOrEmpty(firstValues)){
				throw new IllegalArgumentException(INITIAL_MAP_EMPTY);
			}
			for(Map.Entry<Integer, Double> map : firstValues.entrySet()){
				if(map.getKey() == null){
					throw new IllegalArgumentException(INITIAL_MAP_KEYS_EMPTY);
				}
				if(map.getValue() == null){
					throw new IllegalArgumentException(INITIAL_MAP_VALUES_EMPTY);
				}
			}
			this.initialStacksDouble = firstValues;
			this.logChangesInStacks = false;
			this.shouldIgnoreStringCase = false;
			this.allowStackDuplicates = false;
			this.maintainMinimumOneItemInStack = true;
			this.localStackType = StackType.TypeDouble;
		}

		/**
		 * This builder starts off with as many managed stacks as are needed depending
		 * on the int tag + String combos sent in. IE, if you send in a map with 2 keys:
		 * 0, and 1, and the first String values are "Apple" and "Orange", there will
		 * now be 2 stacks held within the manager each with one item in them and their
		 * corresponding tags will match those passed in here
		 * @param firstItemInStacks A Map of int keys and String values
		 */
		public Builder(@NonNull Map<Integer, Object> firstItemInStacks) throws IllegalArgumentException{
			if(MiscUtilities.isMapNullOrEmpty(firstItemInStacks)){
				throw new IllegalArgumentException(INITIAL_MAP_EMPTY);
			}
			for(Map.Entry<Integer, Object> map : firstItemInStacks.entrySet()){
				if(map.getKey() == null){
					throw new IllegalArgumentException(INITIAL_MAP_KEYS_EMPTY);
				}
				if(map.getValue() == null){
					throw new IllegalArgumentException(INITIAL_MAP_VALUES_EMPTY);
				}
			}
			this.initialStacksGenericObject = firstItemInStacks;
			this.logChangesInStacks = false;
			this.shouldIgnoreStringCase = false;
			this.allowStackDuplicates = false;
			this.maintainMinimumOneItemInStack = true;
			this.localStackType = StackType.TypeGenericObject;
		}

		/**
		 * Should ignore the case of the Strings. Really only utilized when the
		 * {@link StackRawManager.Builder#allowStackDuplicates} is false;
		 * Note, Defaults to false.
		 * @param shouldIgnore If true, will ignore case when setting and if the stack
		 *                     duplicates is false, will act accordingly.
		 *                     IE, if you have "Pat" in the stack and pass in "PAT",
		 *                     it will replace the "Pat" with "PAT" and put it on top.
		 *                     If allow duplicates is true and you have "Pat" in the stack
		 *                     and pass in "PAT", it will add "PAT regardless.
		 * @return
		 */
		public Builder setShouldIgnoreStringCase(boolean shouldIgnore){
			this.shouldIgnoreStringCase = shouldIgnore;
			return this;
		}

		/**
		 * Set whether logging should occur whenever the stack changes.
		 * Note, Defaults to false.
		 * @param shouldLog If true, logs will occur in the logcat whenever
		 *                  the stack changes with either append or pop.
		 * @return
		 */
		public Builder setShouldLogChangesInStacks(boolean shouldLog){
			this.logChangesInStacks = shouldLog;
			return this;
		}

		/**
		 * Should Allow the stack to have duplicates of the same value.
		 * Note, Defaults to false.
		 * @param shouldAllow If true, will allow duplicates of the same String,
		 *                    else, if same string is appended, it will remove it from
		 *                    the position it was in and move it to the top of the list
		 * @return
		 */
		public Builder setShouldAllowStackDuplicates(boolean shouldAllow){
			this.allowStackDuplicates = shouldAllow;
			return this;
		}

		/**
		 * Should Maintain at least one item in a stack.
		 * Note, Defaults to true.
		 * @param shouldKeepAtLeastOne If true, popping the stack will always leave
		 *                             the initial one in place, else it will pop all
		 *                             the way down to zero
		 * @return
		 */
		public Builder setShouldMaintainMinimumOneItemInStack(boolean shouldKeepAtLeastOne){
			this.maintainMinimumOneItemInStack = shouldKeepAtLeastOne;
			return this;
		}

		/**
		 * Build
		 * @return {@link StackRawManager}
		 */
		public StackRawManager build(){
			return new StackRawManager(this);
		}
	}

	//endregion

	//region Constructor

	/**
	 * Constructor, requires Builder Class.
	 * @param builder {@link Builder}
	 */
	private StackRawManager(StackRawManager.Builder builder){
		if(builder == null){
			return;
		}
		this.maintainMinimumOneItemInStack = builder.maintainMinimumOneItemInStack;
		this.allowStackDuplicates = builder.allowStackDuplicates;
		this.shouldIgnoreStringCase = builder.shouldIgnoreStringCase;
		this.logChangesInStacks = builder.logChangesInStacks;
		this.stackType = builder.localStackType;
		this.init(builder.initialStacksString, builder.initialStacksInteger,
				builder.initialStacksLong, builder.initialStacksDouble, builder.initialStacksGenericObject);
	}
	//endregion

	//region Init

	/**
	 * Init method
	 */
	private void init(Map<Integer, String> firstItemsInStackString,
	                  Map<Integer, Integer> firstItemsInStackInteger,
	                  Map<Integer, Long> firstItemsInStackLong,
	                  Map<Integer, Double> firstItemsInStackDouble,
	                  Map<Integer, Object> firstItemsInStackGenericObject) throws StackRawManagerException {
		this.managedStacks = new HashMap<>();
		if(this.stackType == StackType.TypeString){
			for (Map.Entry<Integer, String> map : firstItemsInStackString.entrySet()) {
				if (map == null) {
					continue;
				}
				Integer key = map.getKey();
				String value = map.getValue();
				if (key == null || StringUtilities.isNullOrEmpty(value)) {
					continue;
				}
				Stack<String> stackToManage = new Stack<>();
				stackToManage.push(value);
				CustomStackManagerPOJO pojo = new CustomStackManagerPOJO();
				pojo.setKey(key);
				pojo.setManagedStack(stackToManage);
				this.managedStacks.put(key, pojo);
			}
		} else if (this.stackType == StackType.TypeInteger){
			for (Map.Entry<Integer, Integer> map : firstItemsInStackInteger.entrySet()) {
				if (map == null) {
					continue;
				}
				Integer key = map.getKey();
				Integer value = map.getValue();
				if (key == null || value == null) {
					continue;
				}
				Stack<Integer> stackToManage = new Stack<>();
				stackToManage.push(value);
				CustomStackManagerPOJO pojo = new CustomStackManagerPOJO();
				pojo.setKey(key);
				pojo.setManagedStack(stackToManage);
				this.managedStacks.put(key, pojo);
			}
		} else if (this.stackType == StackType.TypeLong){
			for (Map.Entry<Integer, Long> map : firstItemsInStackLong.entrySet()) {
				if (map == null) {
					continue;
				}
				Integer key = map.getKey();
				Long value = map.getValue();
				if (key == null || value == null) {
					continue;
				}
				Stack<Long> stackToManage = new Stack<>();
				stackToManage.push(value);
				CustomStackManagerPOJO pojo = new CustomStackManagerPOJO();
				pojo.setKey(key);
				pojo.setManagedStack(stackToManage);
				this.managedStacks.put(key, pojo);
			}
		} else if (this.stackType == StackType.TypeDouble){
			for (Map.Entry<Integer, Double> map : firstItemsInStackDouble.entrySet()) {
				if (map == null) {
					continue;
				}
				Integer key = map.getKey();
				Double value = map.getValue();
				if (key == null || value == null) {
					continue;
				}
				Stack<Double> stackToManage = new Stack<>();
				stackToManage.push(value);
				CustomStackManagerPOJO pojo = new CustomStackManagerPOJO();
				pojo.setKey(key);
				pojo.setManagedStack(stackToManage);
				this.managedStacks.put(key, pojo);
			}
		} else if (this.stackType == StackType.TypeGenericObject){
			for (Map.Entry<Integer, Object> map : firstItemsInStackGenericObject.entrySet()) {
				if (map == null) {
					continue;
				}
				Integer key = map.getKey();
				Object value = map.getValue();
				if (key == null || value == null) {
					continue;
				}
				Stack<Object> stackToManage = new Stack<>();
				stackToManage.push(value);
				CustomStackManagerPOJO pojo = new CustomStackManagerPOJO();
				pojo.setKey(key);
				pojo.setManagedStack(stackToManage);
				this.managedStacks.put(key, pojo);
			}
		}
		if (MiscUtilities.isMapNullOrEmpty(this.managedStacks)) {
			throw buildException(INSTANTIATION_ERROR, null, null);
		}
	}

	//endregion

	//region Public Methods for Managing State

	//region Clearing Stacks
	/**
	 * Clear one stack via the tag sent. Follows the boolean rule set via constructor about maintaining
	 * 1 left in the stack if the boolean {@link com.pgmacdesign.pgmactips.stackmanagement.StackRawManager#maintainMinimumOneItemInStack}
	 * is set to true
	 *
	 * @ {@link StackRawManagerException}
	 */
	public void clearOneStack() {
		clearOneStack(0);
	}

	/**
	 * Clear one stack via the tag sent. Follows the boolean rule set via constructor about maintaining
	 * 1 left in the stack if the boolean {@link com.pgmacdesign.pgmactips.stackmanagement.StackRawManager#maintainMinimumOneItemInStack}
	 * is set to true
	 *
	 * @ {@link StackRawManagerException}
	 */
	public void clearOneStack(int tag) {
		try {
			CustomStackManagerPOJO pojo = getStackPOJO(tag);
			if (pojo != null) {
				Stack<String> myStack = (Stack<String>) pojo.getManagedStack();
				if (myStack != null) {
					popTheStack(tag, myStack.size());
				}
			}
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
		}
	}

	/**
	 * Clear all stacks. Follows the boolean rule set via constructor about maintaining
	 * 1 left in the stack if the boolean {@link com.pgmacdesign.pgmactips.stackmanagement.StackRawManager#maintainMinimumOneItemInStack}
	 * is set to true
	 *
	 * @ {@link StackRawManagerException}
	 */
	public void clearAllStacks() {
		for (Map.Entry<Integer, CustomStackManagerPOJO> map : managedStacks.entrySet()) {
			Integer key = map.getKey();
			CustomStackManagerPOJO pojo = map.getValue();
			if (key != null && pojo != null) {
				Stack<String> myStack = (Stack<String>) pojo.getManagedStack();
				if (myStack != null) {
					if(!myStack.isEmpty()){
						popTheStack(key, myStack.size());
					}
				}
			}
		}
	}

	//endregion

	//region Appending Items to the Stack

	/**
	 * Append Strings to the stack (overloaded to allow for position 0 to be used)
	 *
	 * @param strToAdd String to add to the stack
	 * @return String of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public String appendToTheStack(String strToAdd) {
		return appendToTheStack(0, strToAdd);
	}

	/**
	 * Append Integers to the stack (overloaded to allow for position 0 to be used)
	 *
	 * @param strToAdd String to add to the stack
	 * @return String of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public Integer appendToTheStack(Integer strToAdd) {
		return appendToTheStack(0, strToAdd);
	}

	/**
	 * Append Longs to the stack (overloaded to allow for position 0 to be used)
	 *
	 * @param strToAdd String to add to the stack
	 * @return String of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public Long appendToTheStack(Long strToAdd) {
		return appendToTheStack(0, strToAdd);
	}

	/**
	 * Append Doubles to the stack (overloaded to allow for position 0 to be used)
	 *
	 * @param strToAdd String to add to the stack
	 * @return String of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public Double appendToTheStack(Double strToAdd) {
		return appendToTheStack(0, strToAdd);
	}

	/**
	 * Append Strings to the stack
	 *
	 * @param tagToMatchToStrings Int tag to match the map in the constructor
	 * @param strToAdd         String to add / append to the stack
	 * @return String str of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public String appendToTheStack(int tagToMatchToStrings, String strToAdd) {
		try {
			this.manageNullOrEmptyStrings(strToAdd);
			CustomStackManagerPOJO pojo = getStackPOJO(tagToMatchToStrings);
			Stack stack = pojo.getManagedStack();
			if(stack == null){
				return null;
			}
			if(stack.contains(strToAdd)){
				if (allowStackDuplicates) {
					stack.push(strToAdd);
				} else {
					//Replace position to the top
					stack.remove(strToAdd);
					stack.push(strToAdd);
				}
			} else {
				stack.push(strToAdd);
			}
			if (logChangesInStacks) {
				L.m("stack matching tag " + tagToMatchToStrings + " String: " + stack.toString());
			}
			return ((String) stack.peek());
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return null;
		}
	}

	/**
	 * Append Strings to the stack
	 *
	 * @param tagToMatchToStrings Int tag to match the map in the constructor
	 * @param strToAdd         String to add / append to the stack
	 * @return String str of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public Integer appendToTheStack(int tagToMatchToStrings, Integer strToAdd) {
		try {
			this.manageBadArgs(strToAdd);
			CustomStackManagerPOJO pojo = getStackPOJO(tagToMatchToStrings);
			Stack stack = pojo.getManagedStack();
			if(stack == null){
				return null;
			}
			if(stack.contains(strToAdd)){
				if (allowStackDuplicates) {
					stack.push(strToAdd);
				} else {
					//Replace position to the top
					stack.remove(strToAdd);
					stack.push(strToAdd);
				}
			} else {
				stack.push(strToAdd);
			}
			if (logChangesInStacks) {
				L.m("stack matching tag " + tagToMatchToStrings + " Integers: " + stack.toString());
			}
			return ((Integer) stack.peek());
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return null;
		}
	}

	/**
	 * Append Strings to the stack
	 *
	 * @param tagToMatchToStrings Int tag to match the map in the constructor
	 * @param strToAdd         String to add / append to the stack
	 * @return String str of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public Long appendToTheStack(int tagToMatchToStrings, Long strToAdd) {
		try {
			this.manageBadArgs(strToAdd);
			CustomStackManagerPOJO pojo = getStackPOJO(tagToMatchToStrings);
			Stack stack = pojo.getManagedStack();
			if(stack == null){
				return null;
			}
			if(stack.contains(strToAdd)){
				if (allowStackDuplicates) {
					stack.push(strToAdd);
				} else {
					//Replace position to the top
					stack.remove(strToAdd);
					stack.push(strToAdd);
				}
			} else {
				stack.push(strToAdd);
			}
			if (logChangesInStacks) {
				L.m("stack matching tag " + tagToMatchToStrings + " Longs: " + stack.toString());
			}
			return ((Long) stack.peek());
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return null;
		}
	}

	/**
	 * Append Strings to the stack
	 *
	 * @param tagToMatchToStrings Int tag to match the map in the constructor
	 * @param strToAdd         String to add / append to the stack
	 * @return String str of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public Double appendToTheStack(int tagToMatchToStrings, Double strToAdd) {
		try {
			this.manageBadArgs(strToAdd);
			CustomStackManagerPOJO pojo = getStackPOJO(tagToMatchToStrings);
			Stack stack = pojo.getManagedStack();
			if(stack == null){
				return null;
			}
			if(stack.contains(strToAdd)){
				if (allowStackDuplicates) {
					stack.push(strToAdd);
				} else {
					//Replace position to the top
					stack.remove(strToAdd);
					stack.push(strToAdd);
				}
			} else {
				stack.push(strToAdd);
			}
			if (logChangesInStacks) {
				L.m("stack matching tag " + tagToMatchToStrings + " Doubles: " + stack.toString());
			}
			return ((Double) stack.peek());
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return null;
		}
	}

	/**
	 * Append Strings to the stack (overloaded to allow for position 0 to be used)
	 *
	 * @param strsToAdd List of Strings to add / append to the stack
	 * @return String of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public String appendToTheStack(List<String> strsToAdd) {
		return appendToTheStack(0, strsToAdd);
	}

	/**
	 * Append Strings to the stack
	 *
	 * @param tagToMatchToStrings Int tag to match the map in the constructor
	 * @param strsToAdd        List of Strings to add / append to the stack
	 * @return String of the one at the top of the stack
	 * @ {@link StackRawManagerException}
	 */
	public String appendToTheStack(int tagToMatchToStrings, List<String> strsToAdd) {
		try {
			for (String s : strsToAdd) {
				manageNullOrEmptyStrings(s);
			}
			CustomStackManagerPOJO pojo = getStackPOJO(tagToMatchToStrings);
			Stack stack = pojo.getManagedStack();
			if(stack == null){
				return null;
			}
			for(String strToAdd : strsToAdd){
				if(stack.contains(strToAdd)){
					if (allowStackDuplicates) {
						stack.push(strToAdd);
					} else {
						//Replace position to the top
						stack.remove(strToAdd);
						stack.push(strToAdd);
					}
				} else {
					stack.push(strToAdd);
				}
				if (logChangesInStacks) {
					L.m("stack matching tag " + tagToMatchToStrings + " String: " + stack.toString());
				}
			}
			return ((String) stack.peek());
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return null;
		}
	}

	//endregion

	//region Popping the Stack

	/**
	 * Pop the stack matching the int String used. (overloaded to allow for position 0 to be used)
	 *
	 * @return Returns the String at the top of the stack. If the stack is empty, returns null
	 * @ {@link StackRawManagerException}
	 */
	public Object popTheStack() {
		return popTheStack(0);
	}

	/**
	 * Pop the stack matching the int String used.
	 *
	 * @param tagToMatchToStrings Int tag to match the map in the constructor
	 * @return Returns the String at the top of the stack. If the stack is empty, returns null
	 * @ {@link StackRawManagerException}
	 */
	public Object popTheStack(int tagToMatchToStrings) {
		try {
			CustomStackManagerPOJO pojo = getStackPOJO(tagToMatchToStrings);
			Stack stack = pojo.getManagedStack();
			if(stack == null){
				return null;
			}
			int size = stack.size();
			if (maintainMinimumOneItemInStack) {
				if (size > 1) {
					stack.pop();
				}
			} else {
				if (size > 0) {
					stack.pop();
				}
			}
			if (logChangesInStacks) {
				L.m("stack matching tag " + tagToMatchToStrings + " String: " + stack.toString());
			}
			if (size > 0) {
				return stack.peek();
//				switch (this.stackType){
//					case TypeString:
//						return ((String) stack.peek());
//
//					case TypeLong:
//						return ((Long) stack.peek());
//
//					case TypeDouble:
//						return ((Double) stack.peek());
//
//					case TypeInteger:
//						return ((Integer) stack.peek());
//
//					case TypeGenericObject:
//						return ((Object) stack.peek());
//
//				}
			} else {
				return null;
			}
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return null;
		}
	}

	/**
	 * Pop the stack matching the int String used.
	 *
	 * @param tagToMatchToStrings Int tag to match the map in the constructor
	 * @param numToPop          Number to pop off the stack
	 * @return Returns the String at the top of the stack. If the stack is empty, returns null
	 * @ {@link StackRawManagerException}
	 */
	public Object popTheStack(int tagToMatchToStrings, int numToPop) {
		try {
			if (numToPop <= 0) {
				throw buildException(NO_NEGATIVE_NUMBERS_TO_POP, null, tagToMatchToStrings);
			}
			CustomStackManagerPOJO pojo = getStackPOJO(tagToMatchToStrings);
			Stack stack = pojo.getManagedStack();
			if (stack == null) {
				return null;
			}
			int size = stack.size();
			while (numToPop > 0) {
				if (maintainMinimumOneItemInStack) {
					if (size > 1) {
						stack.pop();
					}
				} else {
					if (size > 0) {
						stack.pop();
					}
				}
				numToPop--;
			}
			if (logChangesInStacks) {
				L.m("stack matching tag " + tagToMatchToStrings + " String: " + stack.toString());
			}
			if (size > 0) {
				return (stack.peek());
			} else {
				return null;
			}
		} catch (EmptyStackException ese){
			L.m(ese.getMessage());
			return null;
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return null;
		}
	}

	//endregion

	//region Getter Methods

	/**
	 * Gets the Stack<String>. If no stack is found, print exception and return null
	 * Overloaded to allow for single stack management to be used
	 *
	 * @return {@link Stack<String>}
	 * @ {@link StackRawManagerException}
	 */
	public Stack<Object> getStack() {
		return getStack(0);
	}

	/**
	 * Gets the Stack<String>. If no stack is found, print exception and return null
	 *
	 * @param tag Tag matches one(s) passed in Constructor
	 * @return {@link Stack<String>}
	 * @ {@link StackRawManagerException}
	 */
	public Stack<Object> getStack(int tag) {
		try {
			CustomStackManagerPOJO pojo = getStackPOJO(tag);
			Stack<Object> stackToManage = pojo.getManagedStack();
			return stackToManage;
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return null;
		}
	}

	//endregion

	//endregion

	//region Public Misc Methods

	/**
	 * Get the stack size of the position (int tag) passed
	 * @param pos
	 * @return
	 */
	public int getStackSize(int pos) {
		try {
			Stack stack = getStack(pos);
			return ((stack == null) ? 0 : stack.size());
		} catch (StackRawManagerException sme) {
			L.m(sme.toString());
			return 0;
		}
	}

	/**
	 * Get the stack size of the first managed stack
	 * @return
	 */
	public int getStackSize() {
		return getStackSize(0);
	}

	//endregion

	//region Private Classes

	/**
	 * Checker for whether or not the stack already contains the String passed
	 *
	 * @param stack       Stack containing current Strings
	 * @param strToCheck String to check if it is already included in the stack
	 * @return boolean, if true, stack already contains the String object
	 */
	private boolean stackContainsString(Stack<String> stack, String strToCheck) {
		try {
			for (String e : stack) {
				if(StackRawManager.this.shouldIgnoreStringCase){
					if (e.equalsIgnoreCase(strToCheck)) {
						return true;
					}
				} else {
					if (e.equals(strToCheck)) {
						return true;
					}
				}
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}

	/**
	 * Checker for whether or not the stack already contains the String passed
	 *
	 * @param stack       Stack containing current Strings
	 * @param strToCheck String to check if it is already included in the stack
	 * @return boolean, if true, stack already contains the String object
	 */
	private boolean stackContainsString(Stack<Integer> stack, Integer strToCheck) {
		try {
			for (Integer e : stack) {
				if (e.equals(strToCheck)) {
					return true;
				}
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}

	/**
	 * Checker for whether or not the stack already contains the String passed
	 *
	 * @param stack       Stack containing current Strings
	 * @param strToCheck String to check if it is already included in the stack
	 * @return boolean, if true, stack already contains the String object
	 */
	private boolean stackContainsString(Stack<Long> stack, Long strToCheck) {
		try {
			for (Long e : stack) {
				if (e.equals(strToCheck)) {
					return true;
				}
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}

	/**
	 * Checker for whether or not the stack already contains the String passed
	 *
	 * @param stack       Stack containing current Strings
	 * @param strToCheck String to check if it is already included in the stack
	 * @return boolean, if true, stack already contains the String object
	 */
	private boolean stackContainsString(Stack<Double> stack, Double strToCheck) {
		try {
			for (Double e : stack) {
				if (e.equals(strToCheck)) {
					return true;
				}
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}

	/**
	 * Manage null Strings passed. If null is passed, will throw exception
	 *
	 * @param strWorkingOn
	 * @ {@link StackRawManagerException}
	 */
	private void manageNullOrEmptyStrings(String strWorkingOn) {
		if (StringUtilities.isNullOrEmpty(strWorkingOn)) {
			throw buildException(BAD_STRING, strWorkingOn, null);
		}
	}

	/**
	 * Manage null Objects passed. If null is passed, will throw exception
	 *
	 * @param obj
	 * @ {@link StackRawManagerException}
	 */
	private void manageBadArgs(Object obj) {
		if(obj == null){
			throw buildException(BAD_STRING, obj, null);
		} else {
			if(obj instanceof String){
				manageNullOrEmptyStrings((String)obj);
			}
		}
	}

	/**
	 * Gets the POJO. If null is returned, will throw exception
	 *
	 * @param tag Tag matches one(s) passed in Constructor
	 * @return {@link CustomStackManagerPOJO}
	 * @ {@link StackRawManagerException}
	 */
	private CustomStackManagerPOJO getStackPOJO(int tag) throws StackRawManagerException {
		if (tag < 0 || tag >= this.managedStacks.size()) {
			throw buildException(INVALID_KEY, null, tag);
		}
		CustomStackManagerPOJO pojo = managedStacks.get(tag);
		if (pojo == null) {
			throw buildException(INVALID_KEY, null, tag);
		}
		return pojo;
	}

	//endregion

	//region POJO For Stack Management

	/**
	 * Private class used to manage stacks
	 */
	private class CustomStackManagerPOJO {
		private int key;
		private Stack<String> managedStack;

		int getKey() {
			return key;
		}

		void setKey(int key) {
			this.key = key;
		}

		Stack getManagedStack() {
			return managedStack;
		}

		void setManagedStack(Stack managedStack) {
			this.managedStack = managedStack;
		}
	}

	//endregion

	//region Misc Utilities

	/**
	 * Build the the exception to throw
	 *
	 * @return {@link StackRawManagerException}
	 */
	private StackRawManagerException buildException(String desc, Object strPassed, Integer keyPassed) {
		StackRawManagerException e = new StackRawManagerException();
		if (StringUtilities.isNullOrEmpty(desc)) {
			desc = "An unknown error has occurred";
		}
		e.setErrorMessage(desc);
		e.setKey(keyPassed);
		String str = (strPassed != null) ? strPassed.toString() : "Null";
		e.setStr(str);
		return e;
	}

	//endregion

}


text:
require 'concurrent/atomic/atomic_fixnum'

module Abid
  class Engine
    # Scheduler operates whole job flow execution.
    class Scheduler
      # @return [void]
      def self.invoke(process, *args, invocation_chain: nil)
        task_args = Rake::TaskArguments.new(process.job.arg_names, args)
        invocation_chain ||= Rake::InvocationChain::EMPTY

        detect_circular_dependency(process, invocation_chain)
        new(process, task_args, invocation_chain).invoke
      end

      # @!visibility private

      # Execute given block when DependencyCounter#update is called `count`
      # times.
      class DependencyCounter
        def initialize(count, &block)
          @counter = Concurrent::AtomicFixnum.new(count)
          @block = block
          yield if count <= 0
        end

        def update(*_)
          @block.call if @counter.decrement.zero?
        end
      end

      def self.detect_circular_dependency(process, chain)
        # raise error if process.job is a member of the chain
        new_chain = Rake::InvocationChain.append(process.job, chain)

        process.prerequisites.each do |preq_process|
          detect_circular_dependency(preq_process, new_chain)
        end
      end

      def initialize(process, args, invocation_chain)
        @process = process
        @args = args
        @chain = invocation_chain.conj(@process.job)
        @executor = Executor.new(process, args)
      end

      def invoke
        return unless @executor.prepare

        @process.job.trace_invoke
        attach_chain
        invoke_prerequisites
        after_prerequisites do
          @process.capture_exception do
            @executor.start
          end
        end
      end

      private

      def attach_chain
        @process.on_complete do
          error = @process.error
          next if error.nil?
          next if @chain.nil?

          error.extend(Rake::InvocationExceptionMixin) unless
            error.respond_to?(:chain)
          error.chain ||= @chain
        end
      end

      def invoke_prerequisites
        @process.prerequisites.each do |preq|
          preq_args = @args.new_scope(@process.job.arg_names)
          Scheduler.new(preq, preq_args, @chain).invoke
        end
      end

      def after_prerequisites(&block)
        counter = DependencyCounter.new(@process.prerequisites.size, &block)
        @process.prerequisites.each do |preq|
          preq.on_complete { counter.update }
        end
      end
    end
  end
end


text:
package com.stackmob.sdkapi;

/**
 * A "within" query
 */
public class SMWithin extends SMCondition {
  private final String field;
  private final SMDouble lat;
  private final SMDouble lon;
  private final SMDouble dist;

  /**
   * Create a new SMWithin query
   *
   * @param field the geoField to query
   * @param lat the latitude of the location to search
   * @param lon the longitude of the location to search
   * @param dist the distance, in radians of the search circle
   */
  public SMWithin(String field, SMDouble lat, SMDouble lon, SMDouble dist) {
    this.field = field;
    this.lat = lat;
    this.lon = lon;
    this.dist = dist;
  }

  /**
   * Create a new SMWithin query
   *
   * @param field the geoField to query
   * @param lat the latitude of the location to search
   * @param lon the longitude of the location to search
   * @param dist the distance, in radians of the search circle
   */
  public SMWithin(String field, double lat, double lon, double dist) {
    this.field = field;
    this.lat = new SMDouble(lat);
    this.lon = new SMDouble(lon);
    this.dist = new SMDouble(dist);
  }

  public String getField() {
    return field;
  }

  public SMDouble getLat() {
    return lat;
  }

  public SMDouble getLon() {
    return lon;
  }

  public SMDouble getDist() {
    return dist;
  }

  @Override
  public String toString() {
    return String.format("%s within %s, %s within %s radians", field, lat.toString(), lon.toString(), dist.toString());
  }
}


text:
from hypr import Provider, request, filter
import json

class BaseProvider(Provider):

    def get(self):
        return request.m_filters

class Provider0(BaseProvider):

    propagation_rules = {
        'rule0': (BaseProvider, '/bar')
    }

    @filter
    def my_filter(self):
        return 'ok'

class TestFilter:

    providers = {
        Provider0: '/foo',
    }

    def test_sanity(self, app):
        with app.test_client() as client:
            resp = client.get('/foo')
            assert resp.status == 200
            assert json.loads(resp.text) == {}

    def test_filter_is_applied(self, app):
        with app.test_client() as client:
            resp = client.get('/foo/bar')
            assert resp.status == 200
            assert json.loads(resp.text) == {'my_filter': 'ok'}


text:
require "googleauth"

module Google
  module Cloud
    module OsLogin
      class Credentials < Google::Auth::Credentials
        SCOPE = [
          "https://www.googleapis.com/auth/cloud-platform",
          "https://www.googleapis.com/auth/cloud-platform.read-only",
          "https://www.googleapis.com/auth/compute",
          "https://www.googleapis.com/auth/compute.readonly"
        ].freeze
        PATH_ENV_VARS = %w(OSLOGIN_KEYFILE GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE)
        JSON_ENV_VARS = %w(OSLOGIN_KEYFILE_JSON GOOGLE_CLOUD_KEYFILE_JSON GCLOUD_KEYFILE_JSON)
        DEFAULT_PATHS = ["~/.config/gcloud/application_default_credentials.json"]
      end
    end
  end
end