Very occasionally, we need to get a visitor for another relation, so it makes sense to factor
 these out into a public method despite only being two lines long.
541082
def predicate_visitor
      join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)
      MetaWhere::Visitors::Predicate.new(join_dependency)
    end
311121
function composeJoint(params){
	
	var arrWitnesses = params.witnesses;
	if (!arrWitnesses){
		myWitnesses.readMyWitnesses(function(_arrWitnesses){
			params.witnesses = _arrWitnesses;
			composeJoint(params);
		});
		return;
	}
	
	/*if (conf.bLight && !params.lightProps){
		var network = require('./network.js');
		network.requestFromLightVendor(
			'light/get_parents_and_last_ball_and_witness_list_unit', 
			{witnesses: arrWitnesses}, 
			function(ws, request, response){
				if (response.error)
					return params.callbacks.ifError(response.error);
				if (!response.parent_units || !response.last_stable_mc_ball || !response.last_stable_mc_ball_unit || typeof response.last_stable_mc_ball_mci !== 'number')
					return params.callbacks.ifError("invalid parents from light vendor");
				params.lightProps = response;
				composeJoint(params);
			}
		);
		return;
	}*/
	
	// try to use as few paying_addresses as possible. Assuming paying_addresses are sorted such that the most well-funded addresses come first
	if (params.minimal && !params.send_all){
		var callbacks = params.callbacks;
		var arrCandidatePayingAddresses = params.paying_addresses;

		var trySubset = function(count){
			if (count > constants.MAX_AUTHORS_PER_UNIT)
				return callbacks.ifNotEnoughFunds("Too many authors.  Consider splitting the payment into two units.");
			var try_params = _.clone(params);
			delete try_params.minimal;
			try_params.paying_addresses = arrCandidatePayingAddresses.slice(0, count);
			try_params.callbacks = {
				ifOk: callbacks.ifOk,
				ifError: callbacks.ifError,
				ifNotEnoughFunds: function(error_message){
					if (count === arrCandidatePayingAddresses.length)
						return callbacks.ifNotEnoughFunds(error_message);
					trySubset(count+1); // add one more paying address
				}
			};
			composeJoint(try_params);
		};
		
		return trySubset(1);
	}
	
	var arrSigningAddresses = params.signing_addresses || [];
	var arrPayingAddresses = params.paying_addresses || [];
	var arrOutputs = params.outputs || [];
	var arrMessages = _.clone(params.messages || []);
	var assocPrivatePayloads = params.private_payloads || {}; // those that correspond to a subset of params.messages
	var fnRetrieveMessages = params.retrieveMessages;
//	var lightProps = params.lightProps;
	var signer = params.signer;
	var callbacks = params.callbacks;
	
//	if (conf.bLight && !lightProps)
//		throw Error("no parent props for light");
	
	
	//profiler.start();
	var arrChangeOutputs = arrOutputs.filter(function(output) { return (output.amount === 0); });
	var arrExternalOutputs = arrOutputs.filter(function(output) { return (output.amount > 0); });
	if (arrChangeOutputs.length > 1)
		throw Error("more than one change output");
	if (arrChangeOutputs.length === 0)
		throw Error("no change outputs");
	
	if (arrPayingAddresses.length === 0)
		throw Error("no payers?");
	var arrFromAddresses = _.union(arrSigningAddresses, arrPayingAddresses).sort();
	
	var objPaymentMessage = {
		app: "payment",
		payload_location: "inline",
		payload_hash: hash_placeholder,
		payload: {
			// first output is the change, it has 0 amount (placeholder) that we'll modify later. 
			// Then we'll sort outputs, so the change is not necessarity the first in the final transaction
			outputs: arrChangeOutputs
			// we'll add more outputs below
		}
	};
	var total_amount = 0;
	arrExternalOutputs.forEach(function(output){
		objPaymentMessage.payload.outputs.push(output);
		total_amount += output.amount;
	});
	arrMessages.push(objPaymentMessage);
	
	var bMultiAuthored = (arrFromAddresses.length > 1);
	var objUnit = {
		version: constants.version, 
		alt: constants.alt,
		//timestamp: Date.now(),
		messages: arrMessages,
		authors: []
	};
	var objJoint = {unit: objUnit};
	if (params.earned_headers_commission_recipients) // it needn't be already sorted by address, we'll sort it now
		objUnit.earned_headers_commission_recipients = params.earned_headers_commission_recipients.concat().sort(function(a,b){
			return ((a.address < b.address) ? -1 : 1);
		});
	else if (bMultiAuthored) // by default, the entire earned hc goes to the change address
		objUnit.earned_headers_commission_recipients = [{address: arrChangeOutputs[0].address, earned_headers_commission_share: 100}];
	
	var total_input;
	var last_ball_mci;
	var unlock_callback;
	var conn;
	var lightProps;
	
	var handleError = function(err){
		//profiler.stop('compose');
		unlock_callback();
		if (typeof err === "object"){
			if (err.error_code === "NOT_ENOUGH_FUNDS")
				return callbacks.ifNotEnoughFunds(err.error);
			throw Error("unknown error code in: "+JSON.stringify(err));
		}
		callbacks.ifError(err);
	};
	
	async.series([
		function(cb){ // lock
			mutex.lock(arrFromAddresses.map(function(from_address){ return 'c-'+from_address; }), function(unlock){
				unlock_callback = unlock;
				cb();
			});
		},
		function(cb){ // lightProps
			if (!conf.bLight)
				return cb();
			var network = require('./network.js');
			network.requestFromLightVendor(
				'light/get_parents_and_last_ball_and_witness_list_unit', 
				{witnesses: arrWitnesses}, 
				function(ws, request, response){
					if (response.error)
						return handleError(response.error); // cb is not called
					if (!response.parent_units || !response.last_stable_mc_ball || !response.last_stable_mc_ball_unit || typeof response.last_stable_mc_ball_mci !== 'number')
						return handleError("invalid parents from light vendor"); // cb is not called
					lightProps = response;
					cb();
				}
			);
		},
		function(cb){ // start transaction
			db.takeConnectionFromPool(function(new_conn){
				conn = new_conn;
				conn.query("BEGIN", function(){cb();});
			});
		},
		function(cb){ // parent units
			if (bGenesis)
				return cb();
			
			function checkForUnstablePredecessors(){
				conn.query(
					// is_stable=0 condition is redundant given that last_ball_mci is stable
					"SELECT 1 FROM units CROSS JOIN unit_authors USING(unit) \n\
					WHERE  (main_chain_index>? OR main_chain_index IS NULL) AND address IN(?) AND definition_chash IS NOT NULL \n\
					UNION \n\
					SELECT 1 FROM units JOIN address_definition_changes USING(unit) \n\
					WHERE (main_chain_index>? OR main_chain_index IS NULL) AND address IN(?) \n\
					UNION \n\
					SELECT 1 FROM units CROSS JOIN unit_authors USING(unit) \n\
					WHERE (main_chain_index>? OR main_chain_index IS NULL) AND address IN(?) AND sequence!='good'", 
					[last_ball_mci, arrFromAddresses, last_ball_mci, arrFromAddresses, last_ball_mci, arrFromAddresses],
					function(rows){
						if (rows.length > 0)
							return cb("some definition changes or definitions or nonserials are not stable yet");
						cb();
					}
				);
			}
			
			if (conf.bLight){
				objUnit.parent_units = lightProps.parent_units;
				objUnit.last_ball = lightProps.last_stable_mc_ball;
				objUnit.last_ball_unit = lightProps.last_stable_mc_ball_unit;
				last_ball_mci = lightProps.last_stable_mc_ball_mci;
				objUnit.timestamp = lightProps.timestamp || Math.round(Date.now() / 1000);
				return checkForUnstablePredecessors();
			}
			objUnit.timestamp = Math.round(Date.now() / 1000);
			parentComposer.pickParentUnitsAndLastBall(
				conn, 
				arrWitnesses, 
				objUnit.timestamp,
				function(err, arrParentUnits, last_stable_mc_ball, last_stable_mc_ball_unit, last_stable_mc_ball_mci){
					if (err)
						return cb("unable to find parents: "+err);
					objUnit.parent_units = arrParentUnits;
					objUnit.last_ball = last_stable_mc_ball;
					objUnit.last_ball_unit = last_stable_mc_ball_unit;
					last_ball_mci = last_stable_mc_ball_mci;
					checkForUnstablePredecessors();
				}
			);
		},
		function (cb) { // version
			var bVersion2 = (last_ball_mci >= constants.timestampUpgradeMci);
			if (!bVersion2)
				objUnit.version = constants.versionWithoutTimestamp;
			// calc or fix payload_hash of non-payment messages
			objUnit.messages.forEach(function (message) {
				if (message.app !== 'payment' && message.payload_location === 'inline')
					message.payload_hash = objectHash.getBase64Hash(message.payload, bVersion2);
			});
			cb();
		},
		function(cb){ // authors
			composeAuthorsForAddresses(conn, arrFromAddresses, last_ball_mci, signer, function(err, authors) {
				if (err)
					return cb(err);
				objUnit.authors = authors;
				cb();
			});
		},
		function(cb){ // witnesses
			if (bGenesis){
				objUnit.witnesses = arrWitnesses;
				return cb();
			}
			if (conf.bLight){
				if (lightProps.witness_list_unit)
					objUnit.witness_list_unit = lightProps.witness_list_unit;
				else
					objUnit.witnesses = arrWitnesses;
				return cb();
			}
			// witness addresses must not have references
			storage.determineIfWitnessAddressDefinitionsHaveReferences(conn, arrWitnesses, function(bWithReferences){
				if (bWithReferences)
					return cb("some witnesses have references in their addresses");
				storage.findWitnessListUnit(conn, arrWitnesses, last_ball_mci, function(witness_list_unit){
					if (witness_list_unit)
						objUnit.witness_list_unit = witness_list_unit;
					else
						objUnit.witnesses = arrWitnesses;
					cb();
				});
			});
		},
		// messages retrieved via callback
		function(cb){
			if (!fnRetrieveMessages)
				return cb();
			console.log("will retrieve messages");
			fnRetrieveMessages(conn, last_ball_mci, bMultiAuthored, arrPayingAddresses, function(err, arrMoreMessages, assocMorePrivatePayloads){
				console.log("fnRetrieveMessages callback: err code = "+(err ? err.error_code : ""));
				if (err)
					return cb((typeof err === "string") ? ("unable to add additional messages: "+err) : err);
				Array.prototype.push.apply(objUnit.messages, arrMoreMessages);
				if (assocMorePrivatePayloads && Object.keys(assocMorePrivatePayloads).length > 0)
					for (var payload_hash in assocMorePrivatePayloads)
						assocPrivatePayloads[payload_hash] = assocMorePrivatePayloads[payload_hash];
				cb();
			});
		},
		function(cb){ // input coins
			objUnit.headers_commission = objectLength.getHeadersSize(objUnit);
			var naked_payload_commission = objectLength.getTotalPayloadSize(objUnit); // without input coins

			if (bGenesis){
				var issueInput = {type: "issue", serial_number: 1, amount: constants.TOTAL_WHITEBYTES};
				if (objUnit.authors.length > 1) {
					issueInput.address = arrWitnesses[0];
				}
				objPaymentMessage.payload.inputs = [issueInput];
				objUnit.payload_commission = objectLength.getTotalPayloadSize(objUnit);
				total_input = constants.TOTAL_WHITEBYTES;
				return cb();
			}
			if (params.inputs){ // input coins already selected
				if (!params.input_amount)
					throw Error('inputs but no input_amount');
				total_input = params.input_amount;
				objPaymentMessage.payload.inputs = params.inputs;
				objUnit.payload_commission = objectLength.getTotalPayloadSize(objUnit);
				return cb();
			}
			
			// all inputs must appear before last_ball
			var target_amount = params.send_all ? Infinity : (total_amount + objUnit.headers_commission + naked_payload_commission);
			inputs.pickDivisibleCoinsForAmount(
				conn, null, arrPayingAddresses, last_ball_mci, target_amount, bMultiAuthored, params.spend_unconfirmed || 'own',
				function(arrInputsWithProofs, _total_input){
					if (!arrInputsWithProofs)
						return cb({ 
							error_code: "NOT_ENOUGH_FUNDS", 
							error: "not enough spendable funds from "+arrPayingAddresses+" for "+target_amount
						});
					total_input = _total_input;
					objPaymentMessage.payload.inputs = arrInputsWithProofs.map(function(objInputWithProof){ return objInputWithProof.input; });
					objUnit.payload_commission = objectLength.getTotalPayloadSize(objUnit);
					console.log("inputs increased payload by", objUnit.payload_commission - naked_payload_commission);
					cb();
				}
			);
		}
	], function(err){
		// we close the transaction and release the connection before signing as multisig signing may take very very long
		// however we still keep c-ADDRESS lock to avoid creating accidental doublespends
		conn.query(err ? "ROLLBACK" : "COMMIT", function(){
			conn.release();
			if (err)
				return handleError(err);
			
			// change, payload hash, signature, and unit hash
			var change = total_input - total_amount - objUnit.headers_commission - objUnit.payload_commission;
			if (change <= 0){
				if (!params.send_all)
					throw Error("change="+change+", params="+JSON.stringify(params));
				return handleError({ 
					error_code: "NOT_ENOUGH_FUNDS", 
					error: "not enough spendable funds from "+arrPayingAddresses+" for fees"
				});
			}
			objPaymentMessage.payload.outputs[0].amount = change;
			objPaymentMessage.payload.outputs.sort(sortOutputs);
			objPaymentMessage.payload_hash = objectHash.getBase64Hash(objPaymentMessage.payload, objUnit.version !== constants.versionWithoutTimestamp);
			var text_to_sign = objectHash.getUnitHashToSign(objUnit);
			async.each(
				objUnit.authors,
				function(author, cb2){
					var address = author.address;
					async.each( // different keys sign in parallel (if multisig)
						Object.keys(author.authentifiers),
						function(path, cb3){
							if (signer.sign){
								signer.sign(objUnit, assocPrivatePayloads, address, path, function(err, signature){
									if (err)
										return cb3(err);
									// it can't be accidentally confused with real signature as there are no [ and ] in base64 alphabet
									if (signature === '[refused]')
										return cb3('one of the cosigners refused to sign');
									author.authentifiers[path] = signature;
									cb3();
								});
							}
							else{
								signer.readPrivateKey(address, path, function(err, privKey){
									if (err)
										return cb3(err);
									author.authentifiers[path] = ecdsaSig.sign(text_to_sign, privKey);
									cb3();
								});
							}
						},
						function(err){
							cb2(err);
						}
					);
				},
				function(err){
					if (err)
						return handleError(err);
					objUnit.unit = objectHash.getUnitHash(objUnit);
					if (bGenesis)
						objJoint.ball = objectHash.getBallHash(objUnit.unit);
					console.log(require('util').inspect(objJoint, {depth:null}));
				//	objJoint.unit.timestamp = Math.round(Date.now()/1000); // light clients need timestamp
					if (Object.keys(assocPrivatePayloads).length === 0)
						assocPrivatePayloads = null;
					//profiler.stop('compose');
					callbacks.ifOk(objJoint, assocPrivatePayloads, unlock_callback);
				}
			);
		});
	});
}
128641
function hasManyRemoting (relationName, relation, define) {
  var pathName = (relation.options.http && relation.options.http.path) ||
    relationName
  var toModelName = relation.modelTo.modelName

  var findHasManyRelationshipsFunc = function (cb) {
    this['__get__' + pathName](cb)
  }

  define(
    '__findRelationships__' + relationName,
    {
      isStatic: false,
      accessType: 'READ',
      description: 'Find relations for ' + relationName + '.',
      http: {
        verb: 'get',
        path: '/relationships/' + pathName
      },
      returns: {
        arg: 'result',
        type: toModelName,
        root: true
      },
      rest: {
        after: convertNullToNotFoundError.bind(null, toModelName)
      }
    },
    findHasManyRelationshipsFunc
  )

  // var createRelationshipFunc = function (cb) {
  // TODO: implement this
  // this is where we need to implement
  // POST /:model/:id/relationships/:relatedModel
  //
  // this['__get__' + pathName](cb)
  // }
  // define('__createRelationships__' + relationName, {
  //   isStatic: false,
  //   accessType: 'READ',
  //   description: 'Create relations for ' + relationName + '.',
  //   http: {
  //     verb: 'post',
  //     path: '/relationships/' + pathName
  //   },
  //   returns: {
  //     arg: 'result',
  //     type: toModelName,
  //     root: true
  //   },
  //   rest: {
  //     after: convertNullToNotFoundError.bind(null, toModelName)
  //   }
  // }, createRelationshipFunc)

  // var updateRelationshipsFunc = function (cb) {
  // TODO: implement this
  // this is where we need to implement
  // PATCH /:model/:id/relationships/:relatedModel
  //
  // this['__get__' + pathName](cb)
  // }
  // define('__updateRelationships__' + relationName, {
  //   isStatic: false,
  //   accessType: 'READ',
  //   description: 'Update relations for ' + relationName + '.',
  //   http: {
  //     verb: 'patch',
  //     path: '/relationships/' + pathName
  //   },
  //   returns: {
  //     arg: 'result',
  //     type: toModelName,
  //     root: true
  //   },
  //   rest: {
  //     after: convertNullToNotFoundError.bind(null, toModelName)
  //   }
  // }, updateRelationshipsFunc)

  // var deleteRelationshipsFunc = function (cb) {
  // TODO: implement this
  // this is where we need to implement
  // DELETE /:model/:id/relationships/:relatedModel
  //
  // this['__get__' + pathName](cb)
  // }
  // define('__deleteRelationships__' + relationName, {
  //   isStatic: false,
  //   accessType: 'READ',
  //   description: 'Delete relations for ' + relationName + '.',
  //   http: {
  //     verb: 'delete',
  //     path: '/relationships/' + pathName
  //   },
  //   returns: {
  //     arg: 'result',
  //     type: toModelName,
  //     root: true
  //   },
  //   rest: {
  //     after: convertNullToNotFoundError.bind(null, toModelName)
  //   }
  // }, deleteRelationshipsFunc)

  if (relation.modelThrough || relation.type === 'referencesMany') {
    var modelThrough = relation.modelThrough || relation.modelTo

    var accepts = []
    if (relation.type === 'hasMany' && relation.modelThrough) {
      // Restrict: only hasManyThrough relation can have additional properties
      accepts.push({
        arg: 'data',
        type: modelThrough.modelName,
        http: {
          source: 'body'
        }
      })
    }
  }
}
773514
private void dfs(Visitor visitor, int v, int[] cc, int id) {
        visitor.visit(v);
        cc[v] = id;
        for (int t = 0; t < n; t++) {
            if (graph[v][t] != 0.0) {
                if (cc[t] == -1) {
                    dfs(visitor, t, cc, id);
                }
            }
        }
    }
1048519
public byte[] calculateAgreement(byte[] publicKey, byte[] privateKey) {
    if (publicKey == null || privateKey == null) {
      throw new IllegalArgumentException("Keys must not be null!");
    }

    if (publicKey.length != 32 || privateKey.length != 32) {
      throw new IllegalArgumentException("Keys must be 32 bytes!");
    }

    return provider.calculateAgreement(privateKey, publicKey);
  }
155552
function exposeAttributes(collection) {
    function exposeModelAttributes(item) {
        // Make sure that relations are excluded
        return Object.assign(item, item.serialize({ shallow: true }));
    }
    if (collection) {
        if (collection.hasOwnProperty('length')) {
            return collection.map((item) => { return exposeModelAttributes(item); });
        }
        return exposeModelAttributes(collection);
    }
    return collection;
}
1041837
protected LightweightTypeReference visitTypeArgument(LightweightTypeReference reference, Visiting visiting) {
		return visitTypeArgument(reference, visiting, false);
	}
1324416
public Relation<K,V> create(Relation<K,V> r) {
	// default implementation
	Relation<K,V> r2 = this.create();
	for(K key : r.keys()) {
	    r2.addAll(key, r.getValues(key));
	}
	return r2;
    }
195974
def is_relation_made(relation, keys='private-address'):
    '''
    
    '''
    if isinstance(keys, str):
        keys = [keys]
    for r_id in relation_ids(relation):
        for unit in related_units(r_id):
            context = {}
            for k in keys:
                context[k] = relation_get(k, rid=r_id,
                                          unit=unit)
            if None not in context.values():
                return True
    return False
293481
function visitor(parent) {
    var index = -1
    var children = parent && parent.children

    if (!children) {
      throw new Error('Missing children in `parent` for `visitor`')
    }

    while (++index in children) {
      callback(children[index], index, parent)
    }
  }
1285970
function traverseBroad(object, visitor) {
        var key, child;

        if (!object) {
            return;
        }

        if (visitor.call(null, object) === false) {
            return false;
        }
        for (key in object) {
            if (object.hasOwnProperty(key)) {
                child = object[key];
                if (typeof child === 'object' && child !== null) {
                    traverseBroad(child, visitor);
                }
            }
        }
    }
1310358
def handle_nested_relation(self, line: str, position: int, tokens: ParseResults):
        
        if not self.allow_nested:
            raise NestedRelationWarning(self.get_line_number(), line, position)

        self._handle_relation_harness(line, position, {
            SUBJECT: tokens[SUBJECT],
            RELATION: tokens[RELATION],
            OBJECT: tokens[OBJECT][SUBJECT],
        })

        self._handle_relation_harness(line, position, {
            SUBJECT: tokens[OBJECT][SUBJECT],
            RELATION: tokens[OBJECT][RELATION],
            OBJECT: tokens[OBJECT][OBJECT],
        })
        return tokens
449211
def add(self, relation):
        
        r = Relation(relation)
        key = r.relation_key[0]
        if key not in self.relations:
            self.relations[key] = r
            self.relations[r.relation_key[1]]= r
1310543
private long[] determinePreferenceVectorByApriori(Relation<V> relation, ModifiableDBIDs[] neighborIDs, StringBuilder msg) {
    int dimensionality = neighborIDs.length;

    // database for apriori
    UpdatableDatabase apriori_db = new HashmapDatabase();
    SimpleTypeInformation<?> bitmeta = VectorFieldTypeInformation.typeRequest(BitVector.class, dimensionality, dimensionality);
    for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
      long[] bits = BitsUtil.zero(dimensionality);
      boolean allFalse = true;
      for(int d = 0; d < dimensionality; d++) {
        if(neighborIDs[d].contains(it)) {
          BitsUtil.setI(bits, d);
          allFalse = false;
        }
      }
      if(!allFalse) {
        SingleObjectBundle oaa = new SingleObjectBundle();
        oaa.append(bitmeta, new BitVector(bits, dimensionality));
        apriori_db.insert(oaa);
      }
    }
    APRIORI apriori = new APRIORI(minpts);
    FrequentItemsetsResult aprioriResult = apriori.run(apriori_db);

    // result of apriori
    List<Itemset> frequentItemsets = aprioriResult.getItemsets();
    if(msg != null) {
      msg.append("\n Frequent itemsets: ").append(frequentItemsets);
    }
    int maxSupport = 0, maxCardinality = 0;
    long[] preferenceVector = BitsUtil.zero(dimensionality);
    for(Itemset itemset : frequentItemsets) {
      if((maxCardinality < itemset.length()) || (maxCardinality == itemset.length() && maxSupport == itemset.getSupport())) {
        preferenceVector = Itemset.toBitset(itemset, BitsUtil.zero(dimensionality));
        maxCardinality = itemset.length();
        maxSupport = itemset.getSupport();
      }
    }

    if(msg != null) {
      msg.append("\n preference ") //
          .append(BitsUtil.toStringLow(preferenceVector, dimensionality)) //
          .append('\n');
      LOG.debugFine(msg.toString());
    }

    return preferenceVector;
  }
961824
def allow_relation(self, obj1, obj2, **hints):
        
        if obj1._meta.app_label != 'oldimporter' and obj2._meta.app_label != 'oldimporter':
            return True
        return None
379010
public Relation newRelation(Relational from, Relational to) {
	String newId = idManager.getNextId(AnnotationType.RELATION);
	Relation newRelation = new Relation(newId, from, to);
	annotationContainer.add(newRelation, Layer.RELATIONS, AnnotationType.RELATION);
	return newRelation;
    }
577386
private void calculateContrast(Relation<? extends NumberVector> relation, HiCSSubspace subspace, ArrayList<ArrayDBIDs> subspaceIndex, Random random) {
    final int card = subspace.cardinality();
    final double alpha1 = FastMath.pow(alpha, (1.0 / card));
    final int windowsize = (int) (relation.size() * alpha1);
    final FiniteProgress prog = LOG.isDebugging() ? new FiniteProgress("Monte-Carlo iterations", m, LOG) : null;

    int retries = 0;
    double deviationSum = 0.0;
    for(int i = 0; i < m; i++) {
      // Choose a random set bit.
      int chosen = -1;
      for(int tmp = random.nextInt(card); tmp >= 0; tmp--) {
        chosen = subspace.nextSetBit(chosen + 1);
      }
      // initialize sample
      DBIDs conditionalSample = relation.getDBIDs();

      for(int j = subspace.nextSetBit(0); j >= 0; j = subspace.nextSetBit(j + 1)) {
        if(j == chosen) {
          continue;
        }
        ArrayDBIDs sortedIndices = subspaceIndex.get(j);
        ArrayModifiableDBIDs indexBlock = DBIDUtil.newArray(windowsize);
        // initialize index block
        DBIDArrayIter iter = sortedIndices.iter();
        iter.seek(random.nextInt(relation.size() - windowsize));
        for(int k = 0; k < windowsize; k++, iter.advance()) {
          indexBlock.add(iter); // select index block
        }

        conditionalSample = DBIDUtil.intersection(conditionalSample, indexBlock);
      }
      if(conditionalSample.size() < 10) {
        retries++;
        if(LOG.isDebugging()) {
          LOG.debug("Sample size very small. Retry no. " + retries);
        }
        if(retries >= MAX_RETRIES) {
          LOG.warning("Too many retries, for small samples: " + retries);
        }
        else {
          i--;
          continue;
        }
      }
      // Project conditional set
      double[] sampleValues = new double[conditionalSample.size()];
      {
        int l = 0;
        for(DBIDIter iter = conditionalSample.iter(); iter.valid(); iter.advance()) {
          sampleValues[l++] = relation.get(iter).doubleValue(chosen);
        }
      }
      // Project full set
      double[] fullValues = new double[relation.size()];
      {
        int l = 0;
        for(DBIDIter iter = subspaceIndex.get(chosen).iter(); iter.valid(); iter.advance()) {
          fullValues[l++] = relation.get(iter).doubleValue(chosen);
        }
      }
      double contrast = statTest.deviation(fullValues, sampleValues);
      if(Double.isNaN(contrast)) {
        i--;
        LOG.warning("Contrast was NaN");
        continue;
      }
      deviationSum += contrast;
      LOG.incrementProcessed(prog);
    }
    LOG.ensureCompleted(prog);
    subspace.contrast = deviationSum / m;
  }