public bool contains(SIHJR_PVFS_Particle particle)
 {
     if (particle == _pi || particle == _pj) {
         return true;
     } else {
         return false;
     }
 }
 //checks if the two particles has this spring attached
 public bool consistsOf(SIHJR_PVFS_Particle pi, SIHJR_PVFS_Particle pj)
 {
     if (pi == _pi && pj == _pj) {
         return true;
     } else {
         if (pj == _pi && pi == _pj) {
             return true;
         } else {
             return false;
         }
     }
 }
    private void removeParticle(SIHJR_PVFS_Particle p)
    {
        //remove visual
        _visualController.removeVisualFor (p);
        //remove from list
        _particles.Remove (p);
        //remove all neighbor connections
        //SIHJR_PVFS_Particle pi, pj;
        /*
        foreach (SIHJR_PVFS_Particle pi in _neighborPairsPi) {
            pj = (SIHJR_PVFS_Particle)_neighborPairsPj [_neighborPairsPi.IndexOf (pi)];		//TODO computational nonesense? -> AND WONT WORK -> Change it
            if (pi == p || pj == p) {
                _neighborPairsPi.Remove(p);
                _neighborPairsPj.Remove(p);
            }
        }
        */

        /*
        foreach (SIHJR_PVFS_NeighborPair pair in _neighborPairs) {
            //pj = (SIHJR_PVFS_Particle)_neighborPairsPj [_neighborPairsPi.IndexOf (pi)];
            pi = pair.particle1;
            pj = pair.particle2;

            /*
            if (pi == p || pj == p) {
                _neighborPairsPi.Remove(p);
                _neighborPairsPj.Remove(p);
            }
            * /
            if (pair.contains(p)) {
                _neighborPairs.Remove(pair);
            }
        }
        */
        SIHJR_PVFS_NeighborPair pair;
        for (int i = _neighborPairs.Count - 1; i >= 0; i--) {
            pair = (SIHJR_PVFS_NeighborPair)_neighborPairs [i];
            //pi = pair.particle1;
            //pj = pair.particle2;

            /*
            if (pi == p || pj == p) {
                _neighborPairsPi.Remove(p);
                _neighborPairsPj.Remove(p);
            }
            */
            if (pair.contains (p)) {
                //_neighborPairs.Remove(pair);
                _neighborPairs.RemoveAt (i);
            }
        }
    }
 private float radiiDistance(SIHJR_PVFS_Particle pi, SIHJR_PVFS_Particle pj)
 {
     //pythagoras d = sqrt( |xi-xj|² + |yi-yj|² )
     float a = Mathf.Sqrt (
         Mathf.Pow (pi.x - pj.x, 2) +
         Mathf.Pow (pi.y - pj.y, 2)
         );
     if (float.IsNaN (a)) {
         Debug.Log("IS NAN !!!!!!!! ------------ !!!!!!!! ------------ !!!!!!!! ------------ !!!!!!!! ------------ !!!!!!!!");
         Debug.Log ("[pIDs pi:"+pi.id+"&pj:" + pj.id+"] NAN WAS: pi.x:" + pi.x + ", pj.x:" + pj.x + ", pi.y:" + pi.y + ", pj.y:" + pj.y);
     }
     return a;
     /*
     return Mathf.Sqrt (
         Mathf.Pow (pi.x - pj.x, 2) +
         Mathf.Pow (pi.y - pj.y, 2)
     );
     */
 }
 private Vector2 normalizedDirectionVector(SIHJR_PVFS_Particle pi, SIHJR_PVFS_Particle pj)
 {
     Vector2 temp = new Vector2 ();
     temp.x = pj.x - pi.x;
     temp.y = pj.y - pi.y;
     temp.Normalize ();
     return temp;
 }
    SIHJR_PVFS_Spring addSpring(SIHJR_PVFS_Particle pi, SIHJR_PVFS_Particle pj)
    {
        SIHJR_PVFS_Spring s = null;
        bool alreadyIn = false;
        foreach (SIHJR_PVFS_Spring si in _springs) {
            if (si.consistsOf (pi, pj)) {
                alreadyIn = true;
                s = si;
                break;
            }
        }
        if (alreadyIn == false) {
            s = new SIHJR_PVFS_Spring (pi, pj, _h);
            _springs.Add (s);
            //Debug.Log ("[pIDs pi:"+s.particle1.id+"&pj:" + s.particle2.id+"] ------------------------------------ Spring added");

        } else {
            //this branch should never be reached, but the compiler does need it
            //Debug.Log ("[pIDs pi:"+s.particle1.id+"&pj:" + s.particle2.id+"] ------------------------------------ Spring already inside");

        }
        return s;
    }
    public SIHJR_PVFS_Particle SpawnParticle(float x, float y)
    {
        //int id = nextID();

        //SIHJR_PVFS_Particle p = new SIHJR_PVFS_Particle(id, x, y);
        SIHJR_PVFS_Particle p = new SIHJR_PVFS_Particle (x, y);
        _particles.Add (p);
        _grid.insertParticleToGrid (p);
        return p;
    }
 public SIHJR_PVFS_Spring(SIHJR_PVFS_Particle pi, SIHJR_PVFS_Particle pj, float restLength)
 {
     _pi = pi;
     _pj = pj;
     _restLength = restLength;
 }
 public void moveParticleTo(SIHJR_PVFS_Particle p, SIHJR_PVFS_GridReference gR)
 {
     //p.gridReference
     //Debug.Log ("moveParticleTo-Method -- gridcount OLD before remove: " + _gridArray [p.gridReference.x, p.gridReference.y].Count + " gr["+p.gridReference.x+","+p.gridReference.y+"]");
     _gridArray [p.gridReference.x, p.gridReference.y].Remove (p);
     //Debug.Log ("moveParticleTo-Method -- gridcount OLD after  remove: " + _gridArray [p.gridReference.x, p.gridReference.y].Count + " gr["+p.gridReference.x+","+p.gridReference.y+"]");
     //_gridArray [gR.x, gR.y].Add (p);
     if (_gridArray [gR.x, gR.y] == null) {
         //Debug.Log ("moveParticleTo-Method -- gridcount NEW before remove: null & 0");
     } else {
         //Debug.Log ("moveParticleTo-Method -- gridcount NEW before remove: " + _gridArray [gR.x, gR.y].Count + " gr["+gR.x+","+gR.y+"]");
     }
     insertParticleToGrid (p, gR);
     //Debug.Log ("moveParticleTo-Method -- gridcount NEW after  remove: " + _gridArray [gR.x, gR.y].Count + " gr["+gR.x+","+gR.y+"]");
 }
    public void insertParticleToGrid(SIHJR_PVFS_Particle particle, SIHJR_PVFS_GridReference gR)
    {
        //Debug.Log ("gr: " + gR.x);// + " - gridArray: " + _gridArray[gR.x, gR.y].ToString());

        //insert particle to grid
        if (_gridArray[gR.x, gR.y] == null) {
            //Debug.Log ("null");
            _gridArray[gR.x, gR.y] = new ArrayList ();
        } else {
            //Debug.Log ("not null but: " + _gridArray [0, 0]);
            //_gridArray[gR.x, gR.y].Add (particle);
        }
        _gridArray[gR.x, gR.y].Add(particle);
        //add information of gridreference to particle
        particle.gridReference = gR;
    }
    public void insertParticleToGrid(SIHJR_PVFS_Particle particle)
    {
        //calculate where particle is sistuated on grid
        SIHJR_PVFS_GridReference gR = gridPositionOf(particle);
        insertParticleToGrid (particle, gR);

        //Debug.Log ("inserted AT grX: " + gR.x + ", grY: " + gR.y + " -- thats Count: " + _gridArray[gR.x, gR.y].Count);// + " - gridArray: " + _gridArray[gR.x, gR.y].ToString());

        /*
        Debug.Log ("gr: " + gR.x);// + " - gridArray: " + _gridArray[gR.x, gR.y].ToString());

        //insert particle to grid
        if (_gridArray[gR.x, gR.y] == null) {
            //Debug.Log ("null");
            _gridArray[gR.x, gR.y] = new ArrayList ();
        } else {
            //Debug.Log ("not null but: " + _gridArray [0, 0]);
            //_gridArray[gR.x, gR.y].Add (particle);
            _gridArray[gR.x, gR.y].Add(particle);
        }
        //add information of gridreference to particle
        particle.gridReference = gR;
        */
    }
    public SIHJR_PVFS_GridReference gridPositionOf(SIHJR_PVFS_Particle particle)
    {
        float centerDiffX, centerDiffY;
        int gridX, gridY;

        if (particle.x > _left && particle.x < _right) {
            //calculate difference between center points
            centerDiffX = _bounds.center.x - particle.x;
            //then use the influenceWidth (_h from controller which is the gridWidth)
            centerDiffX = centerDiffX / _influenceWidth;	//can be negative
            //becasue it can be negative, add the difference to the center (half gridWidthCount)
            gridX = (int)Mathf.Ceil (_gridWidthCellCount / 2f + centerDiffX);
        } else {
            gridX = -1;
        }

        if (particle.y > _bottom && particle.y < _top) {
            //calculate difference between center points
            centerDiffY = _bounds.center.y - particle.y;
            //then use the influenceWidth (_h from controller which is the gridWidth)
            centerDiffY = centerDiffY / _influenceWidth;	//can be negative
            //becasue it can be negative, add the difference to the center (half gridWidthCount)
            gridY = (int)Mathf.Ceil (_gridHeightCellCount / 2f + centerDiffY);
        } else {
            gridY = -1;
        }

        SIHJR_PVFS_GridReference gridReference = new SIHJR_PVFS_GridReference (gridX, gridY);
        return gridReference;
    }
 public SIHJR_PVFS_NeighborPair(SIHJR_PVFS_Particle pi, SIHJR_PVFS_Particle pj)
 {
     _pi = pi;
     _pj = pj;
 }