@Project_UUID_IN VARCHAR(255),
@VarName_IN VARCHAR(250), 
@DefinitionObject_UUID_IN VARCHAR(32),
@StmtFrom_IN INTEGER,
@StartPosition_IN INTEGER, 
@NumberOfRows_IN  INTEGER	
AS
BEGIN
SET XACT_ABORT ON
SET NOCOUNT ON

			  -- DECLARATION AREA
				DECLARE @StartPosition INTEGER, @NumberOfRows INTEGER ;
				DECLARE @RC INTEGER = 0, @IsStatementTypeFilter TINYINT = 0 ;
				DECLARE @Project_UUID VARCHAR(255), @DefinitionObject_UUID VARCHAR(32) ;
				DECLARE @VarName VARCHAR(250), @ResourceID INTEGER = 0, @ResourceTypeID INTEGER = 0 ;
				DECLARE @ResourceTypeID_Prog INTEGER = (SELECT TOP 1 ResourceID FROM ResourceTypes WHERE Name = 'PROGRAM') ;


			 -- SET FINAL VALUES FOR WORK VARIABLES
				SET @StartPosition = COALESCE(NULLIF(@StartPosition_IN, -1), 1) ;
			    SET @NumberOfRows  = COALESCE(NULLIF(@NumberOfRows_IN, -1), 2147480000) ; 
				SET @VarName = COALESCE(LTRIM(RTRIM(@VarName_IN)), '') ;
				SET @DefinitionObject_UUID = COALESCE(LTRIM(RTRIM(@DefinitionObject_UUID_IN)), '') ;
				SET @Project_UUID_IN = COALESCE(LTRIM(RTRIM(@Project_UUID_IN)), '!') ;
                
				/*0 stmt from programs, 1 stmt from copybooks, -1 stmt from copybooks and programs*/ 
                IF OBJECT_ID('tempdb..#stmtfrom') IS NOT NULL DROP TABLE #stmtfrom ;  
                CREATE TABLE #stmtfrom (ID INTEGER NOT NULL) ; 
				IF (COALESCE(@StmtFrom_IN, -1) > 0) INSERT INTO #stmtfrom VALUES(1);
				IF (COALESCE(@StmtFrom_IN, -1) = 0) INSERT INTO #stmtfrom VALUES(0);
				IF (COALESCE(@StmtFrom_IN, -1) < 0) INSERT INTO #stmtfrom VALUES(0),(1);
				


				 SELECT @Project_UUID = ProjectGUID
				 FROM  BRD_Status  
				 WHERE BRDID = (SELECT MAX(BRDID) FROM BRD_Status WHERE BRDProcessStatusTypeID = 2) ; -- last BRD succssfull
													 		
				 SET @Project_UUID = COALESCE(LTRIM(RTRIM(@Project_UUID)), '?') ;

				 IF ( @Project_UUID != @Project_UUID_IN) 
					 BEGIN 
								  RAISERROR ('BRD - wrong project.', -- Message text.  
											16, -- Severity.  
											1 -- State.  
											); 
								  RETURN;

					  END;


				-- CHECK if we have to filter by StatementTypeID	  
				IF EXISTS (SELECT 1 FROM #BRDStatementTypeInput)
				BEGIN
						SET @IsStatementTypeFilter = 1 ;
				END ;


				-- DETERMINE definition resource
                SELECT @ResourceID  = ResourceID, @ResourceTypeID = ResourceTypeID FROM BRD_ResourceDetails WHERE ResourceHash LIKE @DefinitionObject_UUID ;
                SET @ResourceID  = COALESCE(@ResourceID, 0) ;
				SET @ResourceTypeID = COALESCE(@ResourceTypeID, 0) ;


				IF (@ResourceID = 0) -- this could be deactivated 
					BEGIN 
								RAISERROR ('BRD - Bad Definition Object.', 16, 1); 
								RETURN;
					END;



			   -- DETERMINE Variable based on filters
			    IF OBJECT_ID('tempdb..#varf63') IS NOT NULL DROP TABLE #varf63 ;
			    CREATE TABLE #varf63 (VarID INTEGER NOT NULL PRIMARY KEY) ;

				INSERT INTO #varf63 (VarID)
			    SELECT v.VarID
				FROM BRD_Variables v 
				WHERE v.VarName  = @VarName
						AND 
						EXISTS (SELECT 1 FROM #BRDVariableHashInput hi WHERE v.VariableHash = hi.VarHash)
						AND  (CASE WHEN @ResourceTypeID = 0                     THEN @ResourceID
								   WHEN @ResourceTypeID = @ResourceTypeID_Prog  THEN v.ProgID
								   ELSE v.CopyID
							   END ) = @ResourceID 
                        AND  (CASE WHEN @ResourceTypeID = 0                     THEN @ResourceTypeID
								   WHEN @ResourceTypeID = @ResourceTypeID_Prog  THEN @ResourceTypeID
								   ELSE v.CopyTypeID
							   END ) = @ResourceTypeID ;



					   -- DETERMINE Statements where variables are involved 
						IF OBJECT_ID('tempdb..#varstmt63') IS NOT NULL DROP TABLE #varstmt63 ;
						SELECT  src2.VarID ,src2.VarIDConsolidate
						       ,src2.StatementCategory, src2.StatementTypeID 
							   ,src2.CopyId, src2.CopyTypeID, src2.ProgID
							   ,src2.PathID ,src2.StartRow ,src2.EndRow ,src2.StartCol ,src2.EndCol
							   ,src2.UsedInCopy, src2.StmtRN, src2.RN 
						INTO #varstmt63 
						FROM (
								   SELECT   src1.VarID  , v.VarIDConsolidate
								           ,src1.StatementCategory, src1.StatementTypeID 
										   ,src1.CopyId, src1.CopyTypeID, src1.ProgID
										   ,src1.PathID ,src1.StartRow ,src1.EndRow ,src1.StartCol ,src1.EndCol
										   ,src1.UsedInCopy
										   ,ROW_NUMBER() OVER(PARTITION BY v.VarIDConsolidate, src1.StatementCategory, src1.StatementTypeID, src1.CopyId, src1.CopyTypeID, src1.PathID ,src1.StartRow ,src1.EndRow ,src1.StartCol ,src1.EndCol ORDER BY src1.ProgID) AS StmtRN 
										   -- try to identify statementes coming from Copy (and pick up only one time ...)
										   ,DENSE_RANK() OVER(ORDER BY src1.CopyId DESC, src1.CopyTypeID, v.VarIDConsolidate, src1.StatementCategory, src1.StatementTypeID,  src1.PathID ,src1.StartRow ,src1.EndRow ,src1.StartCol ,src1.EndCol) AS RN
								   FROM (

												   SELECT  'D' AS StatementCategory
														 ,ds.VarID 
														 ,ds.StatementTypeID
														 ,ds.ProgID
														 ,ds.CopyID
														 ,ds.CopyTypeID
														 ,ds.PathID
														 ,ds.StartRow
														 ,ds.EndRow
														 ,ds.StartCol
														 ,ds.EndCol
														 ,CASE WHEN ds.CopyID IS NOT NULL THEN 1 ELSE 0 END AS UsedInCopy
													FROM BRD_DirectStatements ds 
													WHERE EXISTS (SELECT 1 FROM #varf63 v WHERE ds.VarID = v.VarID)
														  AND ( 
															  @IsStatementTypeFilter = 0
															  OR
															  EXISTS (SELECT 1 FROM #BRDStatementTypeInput f WHERE ds.StatementTypeID = f.StatementTypeID)
															  )

												   UNION 

												   SELECT 'I' AS StatementCategory
														 ,vh.ChildVarID AS VarID 
														 ,ds.StatementTypeID
														 ,ds.ProgID
														 ,ds.CopyID
														 ,ds.CopyTypeID
														 ,ds.PathID
														 ,ds.StartRow
														 ,ds.EndRow
														 ,ds.StartCol
														 ,ds.EndCol
														 ,CASE WHEN ds.CopyID IS NOT NULL THEN 1 ELSE 0 END AS UsedInCopy
												   FROM BRD_DirectStatements ds 
													   INNER JOIN BRD_VariableHierarchy vh ON ds.VarID = vh.VarID 
													WHERE      EXISTS (SELECT 1 FROM #varf63 v WHERE vh.ChildVarID = v.VarID)
														  AND (ds.IsFileIO + ds.IsMQ + ds.IsScreen + ds.Is88VarLvlCondition > 0) 
														  AND ( 
															   @IsStatementTypeFilter = 0
															   OR
															   EXISTS (SELECT 1 FROM #BRDStatementTypeInput f WHERE ds.StatementTypeID = f.StatementTypeID)
															 )
										 )src1 
										     INNER JOIN BRD_Variables v ON src1.VarID = v.VarID
                                         WHERE EXISTS (SELECT 1 FROM  #stmtfrom f WHERE f.ID = src1.UsedInCopy) 
						)src2 ;

						SET @RC = COALESCE((SELECT MAX(RN) FROM #varstmt63), 0) ;  
						


			-- USAGE OUTPUT
			-- Output 1 -> CopyToPrograms 
			   TRUNCATE TABLE #BRDCopyToProgramsOutput ;
			   TRUNCATE TABLE #BRDVariableHashAggregate ;

			   INSERT INTO #BRDCopyToProgramsOutput 
			           (UsageObjectHash, UsingObjectHash, UsingObjectName, UsingObjectType, UsingObjectPathStr, StartRow, EndRow, StartCol, EndCol)
			   SELECT   -- rd1.ResourceID    AS UsageObjectID
			            --,rd1.ResourceTypeID AS UsageObjectType
			            --,rd1.ResourceName  AS UsageObjectName,
			             rd1.ResourceHash  AS UsageObjectHash  
					    --,rd2.ResourceID    AS UsingObjectID
			            ,rd2.ResourceHash  AS UsingObjectHash 
						,rd2.ResourceName  AS UsingObjectName
						,CASE WHEN rd2.ResourceTypeID = 5 THEN 0 ELSE 1 END AS UsingObjectType
						--,c.ResourcePathID
						,pth.PathStr AS UsingObjectPathStr
						,c.StartRow, c.EndRow
						,c.StartCol, c.EndCol
				FROM (
						SELECT  CopyId, CopyTypeID, ProgID
						FROM #varstmt63 vst5
						WHERE CopyID IS NOT NULL 
								AND vst5.RN BETWEEN @StartPosition  AND (@StartPosition + @NumberOfRows - 1) 
						GROUP BY CopyId, CopyTypeID, ProgID
					) src
					    INNER JOIN BRD_ResourceDetails rd1 ON rd1.ResourceID = src.CopyID AND rd1.ResourceTypeID = src.CopyTypeID-- know for sure it is a copy
						INNER JOIN BRD_CopyToResources c ON c.CopyID =  rd1.ResourceID AND c.CopyTypeID = rd1.ResourceTypeID AND c.ResourceID = src.ProgID  
                        INNER JOIN BRD_ResourceDetails rd2 ON  rd2.ResourceID = c.ResourceID AND rd2.ResourceTypeID = c.ResourceTypeID  
				        INNER JOIN BRD_Paths pth ON c.ResourcePathID = pth.PathID ;


                -- Output 2 -> VarHash per statement 
                INSERT INTO #BRDVariableHashAggregate (RN, VarHash)
				SELECT  src.RN, v.VariableHash 
				FROM (
							SELECT DISTINCT VarID ,RN
							FROM #varstmt63 
							WHERE RN BETWEEN @StartPosition  AND (@StartPosition + @NumberOfRows - 1) 
					) src
						INNER JOIN BRD_Variables v ON src.VarID = v.VarID ;

             -- Main Output   
			 -- Output 3 -> Variable Statements
			      SELECT     -- src.VarIDConsolidate,  
						     src.UsedInCopy 
							 --,src.UsageObjectID 
							 --,src.UsageObjectTypeID 
							 ,rd.ResourceHash AS UsageObjectHash  
						     ,rd.ResourceName AS UsageObjectName  
							 --,src.UsageObjectPathID 
							 ,pth1.PathStr AS UsageObjectPath
				             --,src.StatementCategory --,src.StatementTypeID 
							 ,st.Description AS StatementDescription 
							 ,src.StatementPositionStartRow ,src.StatementPositionEndRow 
							 ,src.StatementPositionStartCol ,src.StatementPositionEndCol
				             ,src.RN
						     ,@RC AS NR
				    FROM (
						     SELECT    --VarIDConsolidate,
							             UsedInCopy
									   , CASE WHEN CopyID IS NOT NULL THEN CopyID       ELSE ProgID                 END AS UsageObjectID
									   , CASE WHEN CopyID IS NOT NULL THEN CopyTypeID   ELSE @ResourceTypeID_Prog   END AS UsageObjectTypeID
									   , PathID   AS UsageObjectPathID
									   , StatementCategory
									   , StatementTypeID
									   , StartRow   AS StatementPositionStartRow 
									   , EndRow     AS StatementPositionEndRow 
									   , StartCol   AS StatementPositionStartCol 
									   , EndCol     AS StatementPositionEndCol 
									   , StmtRN
									   , RN
							   FROM #varstmt63 
							   WHERE StmtRN = 1 -- this is for statements that reside in copybooks ... we have to keep only 1
							         AND RN BETWEEN @StartPosition  AND (@StartPosition + @NumberOfRows - 1) 
							) src
							   INNER JOIN BRD_Paths pth1 ON src.UsageObjectPathID = pth1.PathID 
							   INNER JOIN Statements st ON st.StatementType = src.StatementTypeID
							   INNER JOIN BRD_ResourceDetails rd ON rd.ResourceID = src.UsageObjectID AND rd.ResourceTypeID = src.UsageObjectTypeID
					      ORDER BY src.RN
				          OPTION(FAST 500); 


               -- FINAL CLEAN-UP
			      IF OBJECT_ID('tempdb..#stmtfrom')  IS NOT NULL DROP TABLE #stmtfrom ; 
				  IF OBJECT_ID('tempdb..#varf63')    IS NOT NULL DROP TABLE #varf63 ;
				  IF OBJECT_ID('tempdb..#varstmt63') IS NOT NULL DROP TABLE #varstmt63 ;

END;
