//	/**
        //	 * Clear objects cached for efficiency when the
        //	 * object state changes.
        //	 *
        //	 * Messy since state can be changed outside
        //	 * but helps with runtimes.
        //	 */
        //	public void clearCachedObjects(){
        //		graphHash = null;
        ////		hashCode = 0;
        //		groundGraphHash = null;
        //	}
        //

        /**
         * Produces a cheap copy of the graph, where immutable objects
         * (graph structure, static hashes, hash function) are copied by pointer,
         * whereas dynamic objects (dynamic hashes) are shallow-copied
         * @return
         */
        public HashGraph Branch()
        {
            Dictionary <Node, string> dh = new Dictionary <Node, string>(_dynamicHashes);
            HashGraph hg = new HashGraph(_hf, _data, _staticHashes, _blankHash, dh);

            return(hg);
        }
        /**
         * Hash all blank nodes with the mux
         * @param mux
         * @return
         */
        public static void MuxHash(HashGraph hg, string mux)
        {
            HashSet <Node> bnodes = new HashSet <Node>(hg.GetBlankNodeHashes().Keys);

            foreach (var b in bnodes)
            {
                string hc   = hg.GetHash(b);
                var    tup  = new string[] { hc, mux };
                string comb = _hf.CombineOrdered(tup);
                hg.GetBlankNodeHashes().Add(b, comb);
            }
        }
        /**
         * Splits the hashgraph into multiple where each
         * graph represents all triples for each set of connected blank nodes
         * (blank nodes appearing in the same triple).
         *
         * Ground triples are removed (if previously present).
         *
         * Shallow copy: colours are preserved.
         *
         * @return
         */
        public ICollection <HashGraph> BlankNodePartition()
        {
            var part = new Partition <Node>();

            // first create a partition of blank nodes based
            // on being connected
            foreach (Triple t in _data)
            {
                if (t.Subject.IsBlankNode() && t.Object.IsBlankNode() && !t.Subject.Equals(t.Object))
                {
                    part.AddPair(t.Subject as Node, t.Object as Node);
                }
            }

            var pivotToGraph = new Dictionary <Node, HashGraph>();

            foreach (var t in _data)
            {
                // doesn't matter which we pick, both are in the
                // same partition
                BlankNode b = null;
                if (t.Subject.IsBlankNode())
                {
                    b = t.Subject.AsBlankNode();
                }
                else if (t.Object.IsBlankNode())
                {
                    b = t.Object.AsBlankNode();
                }
                else
                {
                    continue;
                }

                // use the lowest bnode in the partition
                // to map to its graph
                var  bp    = part.GetPartition(b);
                Node pivot = null;

                if (bp == null || bp.Count == 0)
                {
                    pivot = b; // singleton ... unconnected blank node
                }
                else
                {
                    pivot = bp[0];
                }

                HashGraph hg;
                if (!pivotToGraph.ContainsKey(pivot))
                {
                    hg = new HashGraph(_hf);
                    pivotToGraph.Add(pivot, hg);
                }
                else
                {
                    hg = pivotToGraph[pivot];
                }
                hg.AddTriple(t);
            }
            return(pivotToGraph.Values);
        }