public Hand parseBinArray(bool[] binaryArray, DepthImagePixel[] depthImageData, double minX, double minY, double maxX, double maxY)
        {
            // Initialize local var
            handMatrix = new bool[Width, Height];
            contourMatrix = new bool[Width, Height];
            trackedHand = new Hand();

            // Conver binaryArray to a binary handMatrix
            int index;
            for (int i = (int)minX; i < (int)maxX; i++)
            {
                for (int j = (int)minY; j < (int)maxY; j++)
                {
                    index = Helper.Point2Index(new Point(i, j));
                    handMatrix[i, j] = binaryArray[index];
                }
            }

            // A point is a inside point if all its adjacent point is part of the hand,
            // otherwise it is a "potential" contour point
            HashSet<Point> potentialPoints = new HashSet<Point>();
            for (int i = (int)minX; i < (int)maxX; i++)
            {
                for (int j = (int)minY; j < (int)maxY; j++)
                {
                    if (handMatrix[i, j])
                    {
                        int adjPointCount = 0;
                        int validPointCount = 0;

                        // Check neighbours for contour
                        if (i > 0)
                        {
                            adjPointCount++;
                            validPointCount = handMatrix[i - 1, j] ? validPointCount + 1 : validPointCount;
                        }
                        if (i < Width - 1)
                        {
                            adjPointCount++;
                            validPointCount = handMatrix[i + 1, j] ? validPointCount + 1 : validPointCount;
                        }
                        if (j > 0)
                        {
                            adjPointCount++;
                            validPointCount = handMatrix[i, j - 1] ? validPointCount + 1 : validPointCount;
                        }
                        if (j < Height - 1)
                        {
                            adjPointCount++;
                            validPointCount = handMatrix[i, j + 1] ? validPointCount + 1 : validPointCount;
                        }

                        if (validPointCount != adjPointCount)
                        {
                            // Is contour
                            contourMatrix[i, j] = true;
                            potentialPoints.Add(new Point(i, j));
                        }
                        else
                        {
                            // Is inside
                            trackedHand.insidePoints.Add(new Point(i, j));
                        }

                    }
                }
            }

            // Get a sorted list of contour points
            List<Point> maxFrontier = new List<Point>();
            while (potentialPoints.Count > 0)
            {
                List<Point> frontier = calculateFrontier(ref potentialPoints);
                if (frontier.Count > maxFrontier.Count)
                {
                    maxFrontier = frontier;
                }
            }
            trackedHand.contourPoints = maxFrontier;

            // Find palm and fingers
            findPalm();
            findFingers(depthImageData);

            return trackedHand;
        }
        /// <summary>
        /// Adds new hand data to recognizer and collect useful data for mapper 
        /// </summary>
        /// <param name="hand"></param>
        public void Add2Buffer(Hand hand)
        {
            // If buffer is full
            if (this.MovingBuffer.Count == mBufferLength)
                this.MovingBuffer.Dequeue();
            if (this.ClickBuffer.Count == cBufferLength)
                this.ClickBuffer.Dequeue();
            if (this.ClickFilter.Count == cFilterLength)
                this.ClickFilter.Dequeue();

            if (hand.fingertips.Count == 0)
            {
                if (++this.zeroCount == 5)
                {
                    // Stopping condition (fives trailing 0s)
                    this.clickCount = this.clickCount / 2;
                    if (this.clickCount > 0)
                    {
                        Console.WriteLine(numFingers + " fingers click " + clickCount + " times");
                        GestureReady(numFingers, clickCount, null);
                    }
                    this.Reset();
                    return;
                }
            }
            else
            {
                // Collects number of fingers
                this.zeroCount = 0;
                this.numFingers = Math.Max(hand.fingertips.Count, this.numFingers);
            }

            // Cursor click setup
            ClickFilter.Enqueue(hand.fingertips.Count > 0 ? 1 : 0);
            this.ClickBuffer.Enqueue(ClickFilter.Average());

            bool tooClose = false;
            this.clickCount = 0;
            // Number of clicks checking with double buffer solution for optimization
            // Optimized from linear to constant
            foreach (double d in this.ClickBuffer)
            {
                if (d == 0.50 && !tooClose)
                {
                    tooClose = true;
                    this.clickCount++;
                }
                else
                    tooClose = false;

            }

            // Cursor move setup
            if (hand.fingertips.Count > 0 && (this.numFingers == 1 || this.numFingers == 2))
            {
                if (this.clickCount == 3 && this.MovingBuffer.Count <  mBufferLength)
                {
                    isDragging = true;
                }
                // Cursor movement condition
                // Added differentiator for dragging
                Point finger = Helper.Convert2DrawingPoint(hand.fingertips[0].point);
                finger.X = (int)((finger.X - relativeX) * xMultiplier * 2);
                finger.Y = (int)((relativeY - finger.Y) * yMultiplier * 2);
                this.MovingBuffer.Enqueue(finger);
                if (this.MovingBuffer.Count == 1)
                {
                    FingerDownPos = this.MovingBuffer.ElementAt(0);
                }
                else if (this.MovingBuffer.Count == mBufferLength)
                {
                    Point pos = new Point();
                    double averageX = this.MovingBuffer.Average(k => k.X);
                    double averageY = this.MovingBuffer.Average(k => k.Y);
                    int scroll = (int)(finger.Y - averageY) * -2 / 3;
                    pos.X = (int)(this.MouseDownPos.X + averageX - FingerDownPos.X);
                    pos.Y = (int)(this.MouseDownPos.Y + averageY - FingerDownPos.Y);
                    GestureReady(this.numFingers, 0, new MapperObject(pos, isDragging, scroll));
                }
            }
        }