text:
'use strict';

require('mocha');
var path = require('path');
var assert = require('assert');
var gm = require('global-modules');
var npm = require('npm-install-global');
var isAbsolute = require('is-absolute');
var exists = require('fs-exists-sync');
var resolve = require('resolve');
var Base = require('..');
var base;

var fixture = path.resolve.bind(path, __dirname, 'fixtures/updaters');
function resolver(search, app) {
  try {
    if (isAbsolute(search.name)) {
      search.name = require.resolve(search.name);
    } else {
      search.name = resolve.sync(search.name, {basedir: gm});
    }
    search.app = app.register(search.name, search.name);
  } catch (err) {}
}

describe('.extendWith', function() {
  before(function(cb) {
    if (!exists(path.resolve(gm, 'generate-bar'))) {
      npm.install('generate-bar', cb);
    } else {
      cb();
    }
  });

  beforeEach(function() {
    base = new Base();
    base.option('toAlias', function(name) {
      return name.replace(/^generate-/, '');
    });

    base.on('unresolved', resolver);
  });

  it.skip('should throw an error when an updater is not found', function(cb) {
    try {
      base.register('foo', function(app) {
        app.extendWith('fofoofofofofof');
      });

      base.getUpdater('foo');
      cb(new Error('expected an error'));
    } catch (err) {
      assert.equal(err.message, 'cannot find updater: "fofoofofofofof"');
      cb();
    }
  });

  it('should extend an updater with settings in the default updater', function(cb) {
    var count = 0;

    base.register('foo', function(app) {
      app.task('default', function(next) {
        assert.equal(app.options.foo, 'bar');
        assert.equal(app.cache.data.foo, 'bar');
        count++;
        next();
      });
    });

    base.register('default', function(app) {
      app.data({foo: 'bar'});
      app.option({foo: 'bar'});
    });

    base.update('foo', function(err) {
      if (err) return cb(err);
      assert.equal(count, 1);
      cb();
    });
  });

  it('should not extend tasks by default', function(cb) {
    var count = 0;

    base.register('foo', function(app) {
      app.task('default', function(next) {
        assert(app.tasks.hasOwnProperty('default'));
        assert(!app.tasks.hasOwnProperty('a'));
        assert(!app.tasks.hasOwnProperty('b'));
        assert(!app.tasks.hasOwnProperty('c'));
        count++;
        next();
      });
    });

    base.register('default', function(app) {
      app.task('a', function(next) {
        next();
      });
      app.task('b', function(next) {
        next();
      });
      app.task('c', function(next) {
        next();
      });
    });

    base.update('foo', function(err) {
      if (err) return cb(err);
      assert.equal(count, 1);
      cb();
    });
  });

  it('should get a named updater', function(cb) {
    var count = 0;

    base.register('foo', function(app) {
      app.extendWith('bar');
      count++;
    });

    base.register('bar', function(app) {
      app.task('a', function() {});
      app.task('b', function() {});
      app.task('c', function() {});
    });

    base.getUpdater('foo');
    assert.equal(count, 1);
    cb();
  });

  it('should extend an updater with a named updater', function(cb) {
    base.register('foo', function(app) {
      assert(!app.tasks.a);
      assert(!app.tasks.b);
      assert(!app.tasks.c);

      app.extendWith('bar');
      assert(app.tasks.a);
      assert(app.tasks.b);
      assert(app.tasks.c);
      cb();
    });

    base.register('bar', function(app) {
      app.task('a', function() {});
      app.task('b', function() {});
      app.task('c', function() {});
    });

    base.getUpdater('foo');
  });

  it('should extend an updater with an array of updaters', function(cb) {
    base.register('foo', function(app) {
      assert(!app.tasks.a);
      assert(!app.tasks.b);
      assert(!app.tasks.c);

      app.extendWith(['bar', 'baz', 'qux']);
      assert(app.tasks.a);
      assert(app.tasks.b);
      assert(app.tasks.c);
      cb();
    });

    base.register('bar', function(app) {
      app.task('a', function() {});
    });

    base.register('baz', function(app) {
      app.task('b', function() {});
    });

    base.register('qux', function(app) {
      app.task('c', function() {});
    });

    base.getUpdater('foo');
  });

  describe('invoke updaters', function(cb) {
    it('should extend with an updater instance', function(cb) {
      base.register('foo', function(app) {
        var bar = app.getUpdater('bar');
        app.extendWith(bar);

        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        assert(app.tasks.hasOwnProperty('c'));
        cb();
      });

      base.register('bar', function(app) {
        app.isBar = true;
        app.task('a', function() {});
        app.task('b', function() {});
        app.task('c', function() {});
      });

      base.getUpdater('foo');
    });

    it('should invoke a named updater', function(cb) {
      base.register('foo', function(app) {
        app.extendWith('bar');

        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        assert(app.tasks.hasOwnProperty('c'));
        cb();
      });

      base.register('bar', function(app) {
        app.task('a', function() {});
        app.task('b', function() {});
        app.task('c', function() {});
      });

      base.getUpdater('foo');
    });
  });

  describe('extend updaters', function(cb) {
    it('should extend an updater with an updater invoked by name', function(cb) {
      base.register('foo', function(app) {
        assert(!app.tasks.a);
        assert(!app.tasks.b);
        assert(!app.tasks.c);

        app.extendWith('bar');
        assert(app.tasks.a);
        assert(app.tasks.b);
        assert(app.tasks.c);
        cb();
      });

      base.register('bar', function(app) {
        app.task('a', function() {});
        app.task('b', function() {});
        app.task('c', function() {});
      });

      base.getUpdater('foo');
    });

    it('should extend an updater with an updater invoked by alias', function(cb) {
      base.register('foo', function(app) {
        assert(!app.tasks.a);
        assert(!app.tasks.b);
        assert(!app.tasks.c);

        app.extendWith('qux');
        assert(app.tasks.a);
        assert(app.tasks.b);
        assert(app.tasks.c);
        cb();
      });

      base.register('generate-qux', function(app) {
        app.task('a', function() {});
        app.task('b', function() {});
        app.task('c', function() {});
      });

      base.getUpdater('qux');
      base.getUpdater('foo');
    });

    it('should extend with an updater invoked by filepath', function(cb) {
      base.register('foo', function(app) {
        assert(!app.tasks.a);
        assert(!app.tasks.b);
        assert(!app.tasks.c);

        app.extendWith(fixture('qux'));
        assert(app.tasks.a);
        assert(app.tasks.b);
        assert(app.tasks.c);
        cb();
      });

      base.getUpdater('foo');
    });

    it('should extend with an updater invoked from node_modules by name', function(cb) {
      base.register('abc', function(app) {
        assert(!app.tasks.a);
        assert(!app.tasks.b);
        assert(!app.tasks.c);

        app.extendWith('generate-foo');
        assert(app.tasks.a);
        assert(app.tasks.b);
        assert(app.tasks.c);
        cb();
      });

      base.getUpdater('abc');
    });

    it('should extend with an updater invoked from node_modules by name on a default instance', function() {
      var app = new Base();

      app.on('unresolved', resolver);
      app.option('toAlias', function(name) {
        return name.replace(/^generate-/, '');
      });

      assert(!app.tasks.a);
      assert(!app.tasks.b);
      assert(!app.tasks.c);

      app.extendWith('generate-foo');
      assert(app.tasks.a);
      assert(app.tasks.b);
      assert(app.tasks.c);
    });

    it('should use an updater from node_modules as a plugin', function() {
      var app = new Base();

      app.option('toAlias', function(name) {
        return name.replace(/^generate-/, '');
      });

      assert(!app.tasks.a);
      assert(!app.tasks.b);
      assert(!app.tasks.c);

      app.use(require('generate-foo'));
      assert(app.tasks.a);
      assert(app.tasks.b);
      assert(app.tasks.c);
    });

    it('should extend with an updater invoked from global modules by name', function(cb) {
      base.register('zzz', function(app) {
        assert(!app.tasks.a);
        assert(!app.tasks.b);
        assert(!app.tasks.c);
        app.extendWith('generate-bar');

        assert(app.tasks.a);
        assert(app.tasks.b);
        assert(app.tasks.c);
        cb();
      });

      base.getUpdater('zzz');
    });

    it('should extend with an updater invoked from global modules by alias', function(cb) {
      base.register('generate-bar');

      base.register('zzz', function(app) {
        assert(!app.tasks.a);
        assert(!app.tasks.b);
        assert(!app.tasks.c);

        app.extendWith('bar');
        assert(app.tasks.a);
        assert(app.tasks.b);
        assert(app.tasks.c);
        cb();
      });

      base.getUpdater('zzz');
    });
  });

  describe('sub-updaters', function(cb) {
    it('should invoke sub-updaters', function(cb) {
      base.register('foo', function(app) {
        app.register('one', function(app) {
          app.task('a', function() {});
        });
        app.register('two', function(app) {
          app.task('b', function() {});
        });

        app.extendWith('one');
        app.extendWith('two');

        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        cb();
      });

      base.getUpdater('foo');
    });

    it('should invoke a sub-updater on the base instance', function(cb) {
      base.register('foo', function(app) {
        app.extendWith('bar.sub');
        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        assert(app.tasks.hasOwnProperty('c'));
        cb();
      });

      base.register('bar', function(app) {
        app.register('sub', function(sub) {
          sub.task('a', function() {});
          sub.task('b', function() {});
          sub.task('c', function() {});
        });
      });

      base.getUpdater('foo');
    });

    it('should invoke a sub-updater from node_modules by name', function(cb) {
      base.register('abc', function(app) {
        assert(!app.tasks.a);
        assert(!app.tasks.b);
        assert(!app.tasks.c);

        app.extendWith('xyz');
        assert(app.tasks.a);
        assert(app.tasks.b);
        assert(app.tasks.c);
        cb();
      });

      base.register('xyz', function(app) {
        app.extendWith('generate-foo');
      });

      base.getUpdater('abc');
    });

    it('should invoke a sub-updater from node_modules by alias', function(cb) {
      base.register('generate-foo');

      base.register('abc', function(app) {
        assert(!app.tasks.a);
        assert(!app.tasks.b);
        assert(!app.tasks.c);

        app.extendWith('xyz');
        assert(app.tasks.a);
        assert(app.tasks.b);
        assert(app.tasks.c);
        cb();
      });

      base.register('xyz', function(app) {
        app.extendWith('foo');
      });

      base.getUpdater('abc');
    });

    it('should invoke an array of sub-updaters', function(cb) {
      base.register('foo', function(app) {
        app.register('one', function(app) {
          app.task('a', function() {});
        });
        app.register('two', function(app) {
          app.task('b', function() {});
        });

        app.extendWith(['one', 'two']);

        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        cb();
      });

      base.getUpdater('foo');
    });

    it('should invoke sub-updaters from sub-updaters', function(cb) {
      base.register('foo', function(app) {
        app.register('one', function(sub) {
          sub.register('a', function(a) {
            a.task('a', function() {});
          });
        });

        app.register('two', function(sub) {
          sub.register('a', function(a) {
            a.task('b', function() {});
          });
        });

        app.extendWith('one.a');
        app.extendWith('two.a');

        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        cb();
      });

      base.getUpdater('foo');
    });

    it('should invoke an array of sub-updaters from sub-updaters', function(cb) {
      base.register('foo', function(app) {
        app.register('one', function(sub) {
          sub.register('a', function(a) {
            a.task('a', function() {});
          });
        });

        app.register('two', function(sub) {
          sub.register('a', function(a) {
            a.task('b', function() {});
          });
        });

        app.extendWith(['one.a', 'two.a']);

        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        cb();
      });

      base.getUpdater('foo');
    });

    it('should invoke sub-updater that invokes another updater', function(cb) {
      base.register('foo', function(app) {
        app.extendWith('bar');
        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        assert(app.tasks.hasOwnProperty('c'));
        cb();
      });

      base.register('bar', function(app) {
        app.extendWith('baz');
      });

      base.register('baz', function(app) {
        app.task('a', function() {});
        app.task('b', function() {});
        app.task('c', function() {});
      });

      base.getUpdater('foo');
    });

    it('should invoke sub-updater that invokes another sub-updater', function(cb) {
      base.register('foo', function(app) {
        app.extendWith('bar.sub');
        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        assert(app.tasks.hasOwnProperty('c'));
        cb();
      });

      base.register('bar', function(app) {
        app.register('sub', function(sub) {
          sub.extendWith('baz.sub');
        });
      });

      base.register('baz', function(app) {
        app.register('sub', function(sub) {
          sub.task('a', function() {});
          sub.task('b', function() {});
          sub.task('c', function() {});
        });
      });

      base.getUpdater('foo');
    });

    it('should invoke sub-updater that invokes another sub-updater', function(cb) {
      base.register('foo', function(app) {
        app.extendWith('bar.sub');
        assert(app.tasks.hasOwnProperty('a'));
        assert(app.tasks.hasOwnProperty('b'));
        assert(app.tasks.hasOwnProperty('c'));
        cb();
      });

      base.register('bar', function(app) {
        app.register('sub', function(sub) {
          sub.extendWith('baz.sub');
        });
      });

      base.register('baz', function(app) {
        app.register('sub', function(sub) {
          sub.task('a', function() {});
          sub.task('b', function() {});
          sub.task('c', function() {});
        });
      });

      base.getUpdater('foo');
    });
  });
});


text:
class MovieTheater < ActiveRecord::Base
  has_many :auditoriums
  has_many :customers
  has_many :users
end

redpajama_set_name: RedPajamaGithub


text:
package testing

import (
	"encoding/json"
	"io"
	"strings"
)

//JSON test type
type JSON map[string]interface{}

//JSONFor tests
func JSONFor(data JSON) io.Reader {
	b, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}

	return strings.NewReader(string(b))
}


text:
CREATE TABLE country (id VARCHAR(2) NOT NULL, name VARCHAR(64) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

INSERT INTO `country` (`id`, `name`) VALUES ('ar', 'Arabic');
INSERT INTO `country` (`id`, `name`) VALUES ('zh', 'Chinese');
INSERT INTO `country` (`id`, `name`) VALUES ('en', 'English');
INSERT INTO `country` (`id`, `name`) VALUES ('fr', 'French');
INSERT INTO `country` (`id`, `name`) VALUES ('de', 'German');
INSERT INTO `country` (`id`, `name`) VALUES ('hi', 'Hindi');
INSERT INTO `country` (`id`, `name`) VALUES ('it', 'Italian');
INSERT INTO `country` (`id`, `name`) VALUES ('ja', 'Japanese');
INSERT INTO `country` (`id`, `name`) VALUES ('pt', 'Portuguese');
INSERT INTO `country` (`id`, `name`) VALUES ('aa', 'Qafar');
INSERT INTO `country` (`id`, `name`) VALUES ('ru', 'Russian');
INSERT INTO `country` (`id`, `name`) VALUES ('es', 'Spanish');


text:
'use strict';

// The background page of the gdb chrome packaged app exists solely to
// manage the set of operations that can only be performed in a v2 chrome app,
// namely those requiring sockets access.
//
// runGdb - Create a nacl module for gdb and marshall its messages.
// rspContinue - Allow a nacl module to run, waiting for it to exit or fault.
// rspDetach - Allow a nacl module to run without monitoring it.
// rspKill - Kill a nacl module by way of its debug port.

/**
 * Compute the checksum of a remote stub command.
 * @param {string} cmd Command to checksum.
 * @return {string} Two digit hex checksum of command.
 */
function rspChecksum_(cmd) {
  var checksum = 0;
  for (var i = 0; i < cmd.length; i++) {
    checksum = (checksum + cmd.charCodeAt(i)) & 0xff;
  }
  var checksumStr = '0' + checksum.toString(16);
  checksumStr = checksumStr.substr(checksumStr.length - 2);
  return checksumStr;
}

/**
 * Convert a string to an ArrayBuffer.
 * @param {string} str.
 * @return {ArrayBuffer}.
 */
function stringToArrayBuffer_(str) {
  var buf = new ArrayBuffer(str.length);
  var view = new Uint8Array(buf);
  for (var i = 0; i < str.length; i++) {
    view[i] = str.charCodeAt(i);
  }
  return buf;
}

/**
 * Add markers and checksum to a remote stub command.
 * @param {string} cmd Command to checksum.
 * @return {string} A ready to send checksumed remote stub message string.
 */
function rspChecksumMessage_(cmd) {
  return '$' + cmd + '#' + rspChecksum_(cmd);
}

/**
 * Add markers and checksum to a remote stub command.
 * @param {string} cmd Command to checksum.
 * @return {string} A ready to send checksumed remote stub message ArrayBuffer.
 */
function rspMessage_(cmd) {
  return stringToArrayBuffer_(rspChecksumMessage_(cmd));
}

/**
 * Decode a remote stub message.
 * @param {string} msg Message to decode.
 * @return {string} The decoded text.
 */
function rspDecode_(msg) {
  var view = new Uint8Array(msg);
  var result = '';
  for (var i = 0; i < msg.byteLength; i++) {
    result += String.fromCharCode(view[i]);
  }
  return result;
}

/**
 * Manage a single debug connection.
 * @private
 * @constructor
 */
function DebugConnection_(port) {
  this.port_ = port;
  this.debugTcpPort_ = null;
  this.socketId_ = null;
  this.gdbEmbed_ = null;

  port.onMessage.addListener(this.handleMessage_.bind(this));
  port.onDisconnect.addListener(this.handleDisconnect_.bind(this));
}

/**
 * Remove the gdb embed if any.
 */
DebugConnection_.prototype.removeEmbed_ = function() {
  if (this.gdbEmbed_ !== null) {
    var p = this.gdbEmbed_.parentNode;
    // Remove the embed from the parent if there is any.
    if (p !== null) {
      p.removeChild(this.gdbEmbed_);
    }
    this.gdbEmbed_ = null;
  }
};

/**
 * Disconnect connection to the debug stub if any.
 */
DebugConnection_.prototype.rspDisconnect_ = function() {
  if (this.socketId_ !== null) {
    chrome.socket.disconnect(this.socketId_);
    chrome.socket.destroy(this.socketId_);
    this.socketId_ = null;
  }
  this.removeEmbed_();
};

/**
 * Set the debug stub port.
 * @param {integer} debugTcpPort.
 */
DebugConnection_.prototype.setDebugTcpPort_ = function(debugTcpPort) {
  this.debugTcpPort_ = debugTcpPort;
};

/**
 * Connect to the debug stub.
 * @param {function()} callback.
 */
DebugConnection_.prototype.rspConnect_ = function(callback) {
  var self = this;
  self.rspDisconnect_();
  chrome.socket.create('tcp', function(createInfo) {
    self.socketId_ = createInfo.socketId;
    chrome.socket.connect(
      self.socketId_, '0.0.0.0', self.debugTcpPort_, function(result) {
        callback();
      });
  });
};

/**
 * Write a command to the debug stub.
 * @param {string} cmd Command to send.
 * @param {function()} callback.
 */
DebugConnection_.prototype.rspSendMessage_ = function(cmd, callback) {
  var msg = rspMessage_(cmd);
  chrome.socket.write(this.socketId_, msg, function(writeInfo) {
    callback();
  });
};

/**
 * Send gdb an interrupt.
 * @param {function()} callback.
 */
DebugConnection_.prototype.rspSendInterrupt_ = function(callback) {
  chrome.socket.write(
      this.socketId_, stringToArrayBuffer_('\x03'), function(writeInfo) {
    callback();
  });
};

/**
 * Connect and send a single command to the debug stub and hangup.
 * @param {string} cmd Command to send.
 * @param {function()} callback.
 */
DebugConnection_.prototype.rspOneCommand_ = function(cmd, callback) {
  var self = this;
  self.rspConnect_(function() {
    self.rspSendMessage_(cmd, function() {
      setTimeout(function() {
        self.rspDisconnect_();
        callback();
      }, 100);
    });
  });
};

/**
 * Wait for a the reply from the debug stub.
 * @param {function(Object)} callback Called on completion with an object
 *                                    containing the decoded and raw message.
 */
DebugConnection_.prototype.rspWait_ = function(callback) {
  var self = this;
  chrome.socket.read(self.socketId_, 1024, function(readInfo) {
    if (readInfo.resultCode > 0) {
      var rawReply = rspDecode_(readInfo.data);
      // The stub sends '+' signs to ack packets.
      // Ignore them as we're relying on TCP to ensure valid transmission.
      if (rawReply === '+') {
        self.rspWait_(callback);
      } else {
        // Messages are sent in the form '$' + message + '#' + checksum.
        // decode the message by slicing out just the message portion.
        var decoded = rawReply.slice(1, rawReply.length - 3);
        // Re-encode the message (adding '$' and '#' + checksum).
        var recoded = rspChecksumMessage_(decoded);
        // Verify the the message is still matches.
        if (recoded !== rawReply) {
          // Since there is a mismatch the message in invalid.
          // Sent a null for the decodedMessage.
          decoded = null;
        }
        callback({
          'reply': decoded,
          'rawReply': rawReply,
        });
      }
    } else {
      self.rspWait_(callback);
    }
  });
};

/**
 * Issue a continue command and wait for a fault.
 * @param {function(Object)} callback Called on completion with a partial
 *                                    decoding of the reply in an
 *                                    rspContinueReply message.
 */
DebugConnection_.prototype.rspContinue_ = function(callback) {
  var self = this;
  self.rspConnect_(function() {
    self.rspSendMessage_('vCont;c', function() {
      self.rspWait_(function(msg) {
        self.rspDisconnect_();
        msg ['name'] = 'rspContinueReply';
        if (msg.reply === null) {
          msg['type'] = 'invalid';
          msg['reply'] = 'INVALID: ' + msg.rawReply;
          callback(msg);
          return;
        }
        var first = msg.reply.slice(0, 1);
        if (['S', 'T', 'W', 'X'].indexOf(first) >= 0) {
          try {
            msg['number'] = parseInt(msg.reply.slice(1, 3), 16);
            msg['type'] = {
              'S': 'signal',
              'T': 'signal',
              'W': 'exited',
              'X': 'terminated',
            }[first];
          } catch (e) {
            msg['type'] = 'invalid';
          }
        } else {
          msg['type'] = 'unexpected';
        }
        callback(msg);
      });
    });
  });
};

/**
 * Issue a kill command.
 * @param {function()} callback.
 */
DebugConnection_.prototype.rspKill_ = function(callback) {
  this.rspOneCommand_('k', callback);
};

/**
 * Issue a detach command.
 * @param {function()} callback.
 */
DebugConnection_.prototype.rspDetach_ = function(callback) {
  this.rspOneCommand_('D', callback);
};

/**
 * Create a new GDB embed.
 */
DebugConnection_.prototype.createGdb_ = function() {
  var self = this;

  // TODO(bradnelson): Figured out why this does not work with an embed an
  // switch it.
  var gdb = document.createElement('object');
  self.gdbEmbed_ = gdb;
  gdb.width = 0;
  gdb.height = 0;
  gdb.type = 'application/x-nacl';
  gdb.data = 'gdb.nmf';

  gdb.addEventListener('message', function(e) {
  if (!self.port_) {
      return;
    }
    if (e.data.indexOf('exited:') === 0) {
      self.port_.postMessage(
          {'name': 'exited',
           'returncode': parseInt(e.data.split(':')[1])});
      gdb.removeEmbed_();
      return;
    }
    self.port_.postMessage({'name': 'message', 'data': e.data});
  });
  gdb.addEventListener('load', function(e) {
    if (!self.port_) {
      return;
    }
    self.port_.postMessage({'name': 'load'});
  });
  gdb.addEventListener('error', function(e) {
    if (!self.port_) {
      return;
    }
    self.port_.postMessage({'name': 'error'});
  });
  gdb.addEventListener('abort', function(e) {
    if (!self.port_) {
      return;
    }
    self.port_.postMessage({'name': 'abort'});
  });
  gdb.addEventListener('crash', function(e) {
    if (!self.port_) {
      return;
    }
    self.port_.postMessage({'name': 'crash'});
  });

  var params = {};
  params['PS_TTY_PREFIX'] = 'gdb';
  params['PS_TTY_RESIZE'] = 'tty_resize';
  params['PS_STDIN'] = '/dev/tty';
  params['PS_STDOUT'] = '/dev/tty';
  params['PS_STDERR'] = '/dev/tty';
  params['PS_VERBOSITY'] = '2';
  params['PS_EXIT_MESSAGE'] = 'exited';
  params['TERM'] = 'xterm-256color';
  params['PWD'] = '/';

  function addParam(name, value) {
    var param = document.createElement('param');
    param.name = name;
    param.value = value;
    gdb.appendChild(param);
  }

  for (var key in params) {
    addParam(key, params[key]);
  }

  var argv = [
      '-ex', 'target remote :' + self.debugTcpPort_,
  ];
  argv = ['gdb.nmf'].concat(argv);

  var argn = 0;
  argv.forEach(function(arg) {
    var argname = 'arg' + argn;
    addParam(argname, arg);
    argn = argn + 1
  });

  document.body.appendChild(gdb);
  // Work around crbug.com/350445
  var junk = gdb.offsetTop;
};

 /**
 * Suspend with javascript, then attach a GDB instance.
 */
DebugConnection_.prototype.runGdb_ = function() {
  var self = this;
  if (self.socketId_ === null) {
    // If we're not connected currently. Connect now.
    self.rspConnect_(function() {
      self.runGdb_();
    });
    return;
  }
  // Break the connection so GDB can attach.
  self.rspSendInterrupt_(function() {
    self.rspDisconnect_();
    self.createGdb_();
  });
};

/**
 * Handle a message from port.
 * @param msg
 */
DebugConnection_.prototype.handleMessage_ = function(msg) {
  var self = this;
  if (msg.name === 'input') {
    if (self.gdbEmbed_ !== null) {
      self.gdbEmbed_.postMessage(msg.msg);
    }
  } else if (msg.name === 'setDebugTcpPort') {
    self.setDebugTcpPort_(msg.debugTcpPort);
    self.port_.postMessage({'name': 'setDebugTcpPortReply'});
  } else if (msg.name === 'runGdb') {
    self.runGdb_();
  } else if (msg.name === 'rspKill') {
    self.rspKill_(function() {
      self.port_.postMessage({'name': 'rspKillReply'});
    });
  } else if (msg.name === 'rspDetach') {
    self.rspDetach_(function() {
      self.port_.postMessage({'name': 'rspDetachReply'});
    });
  } else if (msg.name === 'rspContinue') {
    self.rspContinue_(function(reply) {
      self.port_.postMessage(reply);
    });
  } else if (msg.name === 'installCheck') {
    self.port_.postMessage({'name': 'installCheckReply'});
  }
};

/**
 * Handle a disconnect from port.
 */
DebugConnection_.prototype.handleDisconnect_ = function() {
  this.rspDisconnect_();
  this.port_ = null;
};

/**
 * Create a new DebugConnection for each external connection.
 */
chrome.runtime.onConnectExternal.addListener(function(port) {
  // Check the sender only when not in testing mode.
  if (navigator.userAgent.indexOf('ChromeTestAgent/') < 0) {
    // TODO(bradnelson): Enable this check once a production extension id is
    // known for the debugger extension.
    //if (port.sender.id !== 'blessed-id') {
    //  port.disconnect();
    //  return;
    //}
  }
  var dc = new DebugConnection_(port);
});


text:
struct Threshold : public std::unary_function<FT, unsigned char> {
  double isovalue;
  bool is_identity;

  Threshold(double isovalue) : isovalue(isovalue), is_identity(false) {}

  result_type operator()(FT value)
  {
    if(is_identity)
      return static_cast<unsigned char>(value);
    else if(value >=  isovalue)
      return 1;
    else
      return 0;
  }
};

class Classify_from_isovalue_list :
  public std::unary_function<FT, unsigned char>
{
  typedef std::pair<FT, result_type> Isovalue;
  typedef std::vector<Isovalue> Isovalues;
  boost::shared_ptr<Isovalues> isovalues;
  bool is_identity;

  struct Sort_isovalues : std::binary_function<Isovalue, Isovalue, bool>
  {
    bool operator()(const Isovalue& isoval1, const Isovalue& isoval2)
    {
      return isoval1.first < isoval2.first;
    }
  };
public:
  Classify_from_isovalue_list(Values_list * list)
    : is_identity(false)
  {
    isovalues = boost::shared_ptr<Isovalues>(new Isovalues(list->numberOfValues()));
    for(int i = 0, nbs = list->numberOfValues(); i < nbs; ++i )
      (*isovalues)[i] = std::make_pair(list->value(i), i);
    std::sort(isovalues->begin(), isovalues->end(), Sort_isovalues());
  }

  void set_identity(bool b) {
    is_identity = b;
  }

  result_type operator()(FT value)
  {
    if(is_identity) {
      return static_cast<unsigned char>(value);
    }
    result_type result = 0;
//     std::cerr << "isovalues: ";
    for(int i = 1, end = static_cast<int>(isovalues->size()); i <= end; ++i)
    {
//       std::cerr << (*isovalues)[i-1] << ", ";
      if(value >= (*isovalues)[i-1].first &&
         i >= result)
      {
        result = i;
      }
    }
//     if(result>1)
//       std::cerr << "result = "  << (int)result << "/" << list->numberOfValues() << std::endl;
//     else
//       std::cerr << std::endl;
    if(result>0)
      return (*isovalues)[result-1].second + 1;
    else
      return 0;
  }
};

class Generate_surface_identifiers :
  public std::binary_function<Classify_from_isovalue_list::result_type,
                              Classify_from_isovalue_list::result_type,
                              const QTreeWidgetItem*>
{
  Values_list* list;
  bool labellized;

public:
  Generate_surface_identifiers(Values_list* list)
    : list(list), labellized(false) {};

  void set_labellized_image(bool b)
  {
    labellized = b;
  }

  result_type operator()(const Classify_from_isovalue_list::result_type& a,
                         const Classify_from_isovalue_list::result_type& b)
  {
    if(labellized)
      return list->search((std::max)(a, b));
    else
      return list->item((std::min)(a, b));
  }
};

// class Classify_from_isovalue_list :
//   public std::unary_function<FT, const QTreeWidgetItem*>
// {
//   typedef std::pair<FT, result_type> Isovalue;
//   typedef std::vector<Isovalue> Isovalues;
//   boost::shared_ptr<Isovalues> isovalues;

//   struct Sort_isovalues : std::binary_function<Isovalue, Isovalue, bool>
//   {
//     bool operator()(const Isovalue& isoval1, const Isovalue& isoval2)
//     {
//       return isoval1.first < isoval2.first;
//     }
//   };
// public:
//   Classify_from_isovalue_list(Isovalues_list * list)
//   {
//     isovalues = boost::shared_ptr<Isovalues>(new Isovalues(list->numberOfIsoValues()));
//     for(int i = 0, nbs = list->numberOfIsoValues(); i < nbs; ++i )
//       (*isovalues)[i] = std::make_pair(list->isovalue(i), list->item(i));
//     std::sort(isovalues->begin(), isovalues->end(), Sort_isovalues());
//   }

//   result_type operator()(FT value)
//   {
//     int result = 0;
// //     std::cerr << "isovalues: ";
//     for(int i = 1, end = isovalues->size(); i <= end; ++i)
//     {
// //       std::cerr << (*isovalues)[i-1] << ", ";
//       if(value >= (*isovalues)[i-1].first &&
//          i >= result)
//       {
//         result = i;
//       }
//     }
//     if(result>1)
//       std::cerr << boost::format("result = %1%/%2%\n") % result % isovalues->size();
//     if(result>0)
//       return (*isovalues)[result-1].second;
//     else
//       return 0;
//   }
// };
Volume::Volume(MainWindow* mw) :
  Surface(mw),
  m_sm_angle(30),
  m_sm_radius(0),
  m_sm_distance(0),
  m_relative_precision(0.000000001),
  m_view_surface(false),
  m_triangulation_color(QColor(Qt::green)),
  m_inverse_normals(false),
  two_sides(false),
  del(),
  c2t3(del),
  mw(mw),
  lists_draw_surface(),
  lists_draw_surface_is_valid(false),
#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
  list_draw_marching_cube(0),
  list_draw_marching_cube_is_valid(false),
  lists_draw_surface_mc(),
#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
  m_view_mc(false)
{
  spinBox_radius_bound = mw->findChild<QDoubleSpinBox*>("spinBox_radius_bound");
  spinBox_distance_bound = mw->findChild<QDoubleSpinBox*>("spinBox_distance_bound");
  Q_ASSERT_X(spinBox_radius_bound && spinBox_distance_bound,
             "Volume::Volume()", "Cannot find spinboxes!");

  values_list = mw->values;

  connect(spinBox_radius_bound, SIGNAL(valueChanged(double)),
          this, SLOT(set_radius_bound(double)));
  connect(spinBox_distance_bound, SIGNAL(valueChanged(double)),
          this, SLOT(set_distance_bound(double)));

  connect(mw->actionSurface_mesher, SIGNAL(triggered()),
          this, SLOT(display_surface_mesher_result()));

  connect(mw->actionInverse_normals, SIGNAL(toggled(bool)),
          this, SLOT(set_inverse_normals(bool)));
  m_inverse_normals = mw->actionInverse_normals->isChecked();

  connect(mw->actionDisplay_front_and_back, SIGNAL(toggled(bool)),
          this, SLOT(set_two_sides(bool)));
  two_sides = mw->actionDisplay_front_and_back->isChecked();

  connect(mw->actionDraw_triangles_edges, SIGNAL(toggled(bool)),
          this, SLOT(set_draw_triangles_edges(bool)));
  draw_triangles_edges = mw->actionDraw_triangles_edges->isChecked();

  connect(mw->actionUse_Gouraud_shading, SIGNAL(toggled(bool)),
          this, SLOT(set_use_gouraud(bool)));
  use_gouraud = mw->actionUse_Gouraud_shading->isChecked();

  connect(mw->actionShow_the_image_bounding_box, SIGNAL(toggled(bool)),
          this, SLOT(set_show_bbox(bool)));
  show_bbox = mw->actionShow_the_image_bounding_box->isChecked();

  connect(mw->actionShow_triangulation, SIGNAL(toggled(bool)),
          this, SLOT(set_draw_triangulation(bool)));
  m_draw_triangulation = mw->actionShow_triangulation->isChecked();

  connect(mw->actionTriangulation_edges_color, SIGNAL(triggered()),
          this, SLOT(set_triangulation_edges_color()));

  connect(this, SIGNAL(new_bounding_box(double, double, double, double, double, double)),
          mw->viewer, SLOT(interpolateToFitBoundingBox(double, double, double, double, double, double)));

  connect(values_list, SIGNAL(values_changed()),
          this, SLOT(changed_parameters()));
  connect(values_list, SIGNAL(changed()),
          mw->viewer, SLOT(updateGL()));
  connect(this, SIGNAL(changed()),
          this, SLOT(check_can_export_off()));

  connect(mw->labellizedRadioButton, SIGNAL(toggled(bool)),
	  this, SLOT(labellizedToogled(bool)));

  mw->actionExport_surface_mesh_to_OFF->setEnabled(false);
  connect(mw->actionExport_surface_mesh_to_OFF, SIGNAL(triggered()),
          this, SLOT(export_off()));

  connect(mw->actionSave, SIGNAL(triggered()),
          this, SLOT(save_image_to_inr()));

#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
  connect(mw->actionMarching_cubes, SIGNAL(triggered()),
          this, SLOT(display_marchin_cube()));
#endif
}

void Volume::set_inverse_normals(const bool b) {
  m_inverse_normals = b;

  list_draw_marching_cube = 0; // Invalidate the display list for the
                               // marching cube. See gl_draw_marchingcube()
                               // for an explanation.

  Q_EMIT changed();
}

void Volume::set_two_sides(const bool b) {
  two_sides = b;
  Q_EMIT changed();
}

void Volume::set_draw_triangles_edges(const bool b) {
  draw_triangles_edges = b;
  Q_EMIT changed();
}

void Volume::set_draw_triangulation(const bool b) {
  m_draw_triangulation = b;
  Q_EMIT changed();
}

void Volume::set_triangulation_edges_color() {
  const QColor color = QColorDialog::getColor(m_triangulation_color, mw);
  if (color.isValid()) {
    m_triangulation_color = color;
    Q_EMIT changed();
  }
}

void Volume::set_use_gouraud(const bool b) {
  use_gouraud = b;
  Q_EMIT changed();
}

void Volume::set_show_bbox(const bool b) {
  show_bbox = b;
  Q_EMIT changed();
}

void Volume::only_in()
{
  mw->show_only("volume");
#ifndef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
  mw->actionMarching_cubes->setVisible(false);
#endif
}

#ifdef CGAL_USE_VTK

#include <CGAL/read_vtk_image_data.h>

#include <vtkImageData.h>
#include <vtkDICOMImageReader.h>
#include <vtkImageReader.h>
#include <vtkImageGaussianSmooth.h>
#include <vtkDemandDrivenPipeline.h>

Volume::~Volume()
{
  if(vtk_reader) vtk_reader->Delete();
  if(vtk_image) vtk_image->Delete();
  if(dicom_reader) dicom_reader->Delete();
  if(executive) executive->Delete();
  if(smoother) smoother->Delete();
}

bool Volume::opendir(const QString& dirname)
{
  bool result = true;
  if(!fileinfo.isReadable())
  {
    QMessageBox::warning(mw, mw->windowTitle(),
                         tr("Cannot read directory <tt>%1</tt>!").arg(dirname));
    status_message(tr("Opening of directory %1 failed!").arg(dirname));
    result = false;
  }
  else
  {
    dicom_reader = vtkDICOMImageReader::New();
    dicom_reader->SetDirectoryName(dirname.toUtf8());

    executive =
      vtkDemandDrivenPipeline::SafeDownCast(dicom_reader->GetExecutive());
    if (executive)
    {
      executive->SetReleaseDataFlag(0, 0); // where 0 is the port index
    }

    smoother = vtkImageGaussianSmooth::New();
    smoother->SetStandardDeviations(1., 1., 1.);
    smoother->SetInputConnection(dicom_reader->GetOutputPort());
    smoother->Update();
    vtk_image = smoother->GetOutput();
    vtk_image->Print(std::cerr);
    m_image = CGAL::read_vtk_image_data(vtk_image);
    if(m_image.image() == 0)
    {
      QMessageBox::warning(mw, mw->windowTitle(),
                           tr("Error with file <tt>%1/</tt>:\nunknown file format!").arg(dirname));
      status_message(tr("Opening of file %1/ failed!").arg(dirname));
      result = false;
    }
    else
    {
      status_message(tr("File %1/ successfully opened.").arg(dirname));
      finish_open();
      result = true;
    }
    // if(executive) executive->Delete();
    // dicom_reader->Delete();
    // smoother->Delete();
  }
  return result;
}

bool Volume::open_vtk(const QString& filename)
{
  only_in();

  fileinfo.setFile(filename);

  if(fileinfo.isDir())
  {
    return opendir(filename);
  }

  if(!fileinfo.isReadable())
  {
    QMessageBox::warning(mw, mw->windowTitle(),
                         tr("Cannot read file <tt>%1</tt>!").arg(filename));
    status_message(tr("Opening of file %1 failed!").arg(filename));
    return false;
  }
  else
  {
    vtk_reader = vtkImageReader::New();
    vtk_reader->SetFileName(filename.toUtf8());
    vtk_reader->SetDataScalarTypeToUnsignedChar();
    vtk_reader->SetDataExtent(0, 249, 0, 249, 0,  124);
    vtk_reader->SetDataSpacing(1., 1., 1.);
    vtk_reader->SetFileDimensionality(3);
    vtk_reader->Update();
    vtk_reader->Print(std::cerr);
    vtk_image = vtk_reader->GetOutput();
    vtk_image->Print(std::cerr);
    m_image = CGAL::read_vtk_image_data(vtk_image);
    if(m_image.image() == NULL)
    {
      QMessageBox::warning(mw, mw->windowTitle(),
                           tr("Error with file <tt>%1</tt>:\nunknown file format!").arg(filename));
      status_message(tr("Opening of file %1 failed!").arg(filename));
      return false;
    }
    else
    {
      status_message(tr("File %1 successfully opened.").arg(filename));
      finish_open();
      return true;
    }
  }
}

// Total 3D images (XT format, that is the old Inrimage format, 1994.
bool Volume::open_xt(const QString& filename)
{
  only_in();

  fileinfo.setFile(filename);

  if(fileinfo.isDir())
  {
    return false;
  }

  if(!fileinfo.isReadable())
  {
    QMessageBox::warning(mw, mw->windowTitle(),
                         tr("Cannot read file <tt>%1</tt>!").arg(filename));
    status_message(tr("Opening of file %1 failed!").arg(filename));
    return false;
  }
  else
  {
    long dimx, dimy, dimz;
    long word_dim;
    long header_size;
    const char* filename_stl = qPrintable(filename);
    CGAL::Total::lire_longueur_entete(filename_stl, &header_size);
    CGAL::Total::lire_nb_octet(filename_stl, &word_dim);
    CGAL::Total::lire_longueur_trace(filename_stl, &dimx);
    CGAL::Total::lire_nb_trace(filename_stl, &dimy);
    CGAL::Total::lire_nb_plan(filename_stl, &dimz);

    vtkImageReader* vtk_reader = vtkImageReader::New();
    vtk_reader->SetFileName(filename_stl);
    switch(word_dim) {
    case 8:
      vtk_reader->SetDataScalarTypeToUnsignedChar();
      break;
    case 16:
      vtk_reader->SetDataScalarTypeToUnsignedShort();
      break;
    default:
      return false;
    }
    vtk_reader->SetHeaderSize(header_size);
    vtk_reader->SetDataExtent(1, dimx, 1, dimy, 1,  dimz);
    vtk_reader->SetDataSpacing(1., 1., 1.);
    vtk_reader->SetFileDimensionality(3);
    vtk_reader->Update();
    vtk_reader->Print(std::cerr);
    vtkImageData* vtk_image = vtk_reader->GetOutput();
    vtk_image->Print(std::cerr);
    m_image = CGAL::read_vtk_image_data(vtk_image);
    if(m_image.image() != NULL)
    {
      QMessageBox::warning(mw, mw->windowTitle(),
                           tr("Error with file <tt>%1</tt>:\nunknown file format!").arg(filename));
      status_message(tr("Opening of file %1 failed!").arg(filename));
      return false;
    }
    else
    {
      status_message(tr("File %1 successfully opened.").arg(filename));
      finish_open();
    }
    return true;
  }
}

#else // CGAL_USE_VTK
Volume::~Volume()
{
}

bool Volume::opendir(const QString&)
{
  return false;
}

bool Volume::open_xt(const QString&)
{
  return false;
}
#endif // CGAL_USE_VTK

bool Volume::open(const QString& filename)
{
  only_in();

  fileinfo.setFile(filename);

  if(fileinfo.isDir())
  {
    return opendir(filename);
  }

  if(!fileinfo.isReadable())
  {
    QMessageBox::warning(mw, mw->windowTitle(),
                         tr("Cannot read file <tt>%1</tt>!").arg(filename));
  }
  else
  {
    if(m_image.read(filename.toStdString().c_str()))
    {
      status_message(tr("File %1 successfully opened.").arg(filename));
      finish_open();
      return true;
    }
    else if(open_xt(filename)) {
      return true;
    }
    else
    {
      QSettings settings;
      settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath()));
      if( settings.value("is_raw").toBool() &&
	  m_image.read_raw(filename.toStdString().c_str(),
			   settings.value("dim_x").toInt(),
			   settings.value("dim_y").toInt(),
			   settings.value("dim_z").toInt(),
			   settings.value("spacing_x").toDouble(),
			   settings.value("spacing_y").toDouble(),
			   settings.value("spacing_z").toDouble(),
			   settings.value("offset").toInt()) )
      {
	status_message(tr("File %1 successfully opened.").arg(filename));
	finish_open();
	return true;
      }
      else if(QMessageBox::warning(mw, mw->windowTitle(),
				   tr("Error with file <tt>%1</tt>:\n"
				      "unknown file format!\n"
				      "\n"
				      "Open it as a raw image?").arg(filename),
				   QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes)
      {
	Raw_image_dialog raw_dialog;
	raw_dialog.label_file_size->setText(QString("%1 B").arg(fileinfo.size()));
	if( raw_dialog.exec() &&
	    m_image.read_raw(filename.toStdString().c_str(),
			     raw_dialog.dim_x->value(),
			     raw_dialog.dim_y->value(),
			     raw_dialog.dim_z->value(),
			     raw_dialog.spacing_x->value(),
			     raw_dialog.spacing_y->value(),
			     raw_dialog.spacing_z->value(),
			     raw_dialog.offset->value()) )
	{
	  status_message(tr("File %1 successfully opened.").arg(filename));
	  QSettings settings;
	  settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath()));
	  settings.setValue("is_raw", true);
	  settings.setValue("dim_x", raw_dialog.dim_x->value());
	  settings.setValue("dim_y", raw_dialog.dim_y->value());
	  settings.setValue("dim_z", raw_dialog.dim_z->value());
	  settings.setValue("spacing_x", raw_dialog.spacing_x->value());
	  settings.setValue("spacing_y", raw_dialog.spacing_y->value());
	  settings.setValue("spacing_z", raw_dialog.spacing_z->value());
	  settings.setValue("offset", raw_dialog.offset->value());
	  settings.endGroup();
	  finish_open();
	  return true;
	}
      }
    }
  }
  status_message(tr("Opening of file %1 failed!").arg(filename));
  return false;
}

void Volume::finish_open()
{
  m_image.finish_open();
  mw->viewer->camera()->setSceneBoundingBox(qglviewer::Vec(0, 0, 0),
                                            qglviewer::Vec(m_image.xmax(),
                                                           m_image.ymax(),
                                                           m_image.zmax()));

  mw->viewer->showEntireScene();
  values_list->load_values(fileinfo.absoluteFilePath());
  load_image_settings(fileinfo.absoluteFilePath());
  changed_parameters();
  Q_EMIT changed();
}

void Volume::export_off()
{
  QFileDialog filedialog(mw, tr("Export surface to file"));
  filedialog.setFileMode(QFileDialog::AnyFile);

  filedialog.setNameFilter(tr("OFF files (*.off);;"
                              "All files (*)"));

  filedialog.setAcceptMode(QFileDialog::AcceptSave);
  filedialog.setDefaultSuffix("off");
  if(filedialog.exec())
  {
    const QString filename = filedialog.selectedFiles().front();
    std::cerr << "Saving to file \"" << filename.toLocal8Bit().data() << "\"...";
    std::ofstream out(filename.toUtf8());
    CGAL::output_surface_facets_to_off(out, c2t3);
    if(!out)
    {
      QMessageBox::warning(mw, mw->windowTitle(),
                           tr("Export to the OFF file <tt>%1</tt> failed!").arg(filename));
      status_message(tr("Export to the OFF file %1 failed!").arg(filename));
      std::cerr << " failed!\n";
    }
    else
    {
      std::cerr << " done.\n";
      status_message(tr("Successfull export to the OFF file %1.").arg(filename));
    }
  }
}

void Volume::save_image_to_inr()
{
  QFileDialog filedialog(mw, tr("Export image to Inrimage format"));
  filedialog.setFileMode(QFileDialog::AnyFile);

  filedialog.setNameFilter(tr("Inrimage files (*.inr);;"
                              "Compressed Inrimage files (*.inr.gz)"));

  filedialog.setAcceptMode(QFileDialog::AcceptSave);
  filedialog.setDefaultSuffix("inr.gz");
  if(filedialog.exec())
  {
    const QString filename = filedialog.selectedFiles().front();
    std::cerr << "Saving image to file \"" << filename.toLocal8Bit().data() << "\"...";
    const int result = ::_writeImage(m_image.image(), filename.toUtf8());
    if(result != ImageIO_NO_ERROR)
    {
      QMessageBox::warning(mw, mw->windowTitle(),
                           tr("Export to the Inrimage file <tt>%1</tt> failed!").arg(filename));
      status_message(tr("Export to the Inrimage file %1 failed!").arg(filename));
      std::cerr << " failed!\n";
    }
    else
    {
      std::cerr << " done.\n";
      status_message(tr("Successfull export to the Inrimage file %1.").arg(filename));
    }
  }
}

void Volume::check_can_export_off()
{
  mw->actionExport_surface_mesh_to_OFF->setEnabled(m_view_surface);// || m_view_mc);
}

void Volume::status_message(QString string)
{
  std::cerr << qPrintable(string) << std::endl;
  mw->statusBar()->showMessage(string);
}

void Volume::busy() const
{
  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
}

void Volume::not_busy() const
{
  QApplication::restoreOverrideCursor();
}

void Volume::display_marchin_cube()
{
#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
  if(m_surface_mc.empty())
  {
    QTime total_time;
    total_time.start();

    values_list->save_values(fileinfo.absoluteFilePath());

    unsigned int nx = m_image.xdim();
    unsigned int ny = m_image.ydim();
    unsigned int nz = m_image.zdim();
    if(nx * ny * nz == 0)
    {
      status_message("No volume loaded.");
      return;
    }

    mc_timer.reset();
    busy();
    status_message("Marching cubes...");

    mc_timer.start();
    m_surface_mc.clear();

    if(mc.ntrigs()!=0)
      mc.clean_all();
    mc.set_resolution(nx,ny,nz);
    mc.init_all();
    mc.set_ext_data(static_cast<unsigned char*>(m_image.image()->data));

    nbs_of_mc_triangles.resize(values_list->numberOfValues());

    for(int value_id = 0;
        value_id < values_list->numberOfValues();
        ++value_id)
    {
      status_message(tr("Marching cubes, isovalue #%1...").arg(value_id));

      // set data
//       for(unsigned int i=0;i<nx;i++)
//         for(unsigned int j=0;j<ny;j++)
//           for(unsigned int k=0;k<nz;k++)
//           {
//             const float& value = m_image.value(i,j,k);
//             mc.set_data(value,i,j,k);
//           }
      // compute scaling ratio
      if(value_id > 0)
        mc.init_temps();
      mc.run(values_list->value(value_id),
             m_image.vx(),
             m_image.vy(),
             m_image.vz());
      mc.clean_temps();

      std::vector<double> facets;
      mc.get_facets(facets);

      mc_timer.stop();
      const unsigned int begin = value_id == 0 ? 0 : nbs_of_mc_triangles[value_id-1];
      const unsigned int nbt = facets.size() / 9;
      for(unsigned int i=begin;i<nbt;i++)
      {
        const Point a(facets[9*i],   facets[9*i+1], facets[9*i+2]);
        const Point b(facets[9*i+3], facets[9*i+4], facets[9*i+5]);
        const Point c(facets[9*i+6], facets[9*i+7], facets[9*i+8]);
        const Triangle_3 t(a,b,c);
        const Vector u = t[1] - t[0];
        const Vector v = t[2] - t[0];
        Vector n = CGAL::cross_product(u,v);
        n = n / std::sqrt(n*n);
        m_surface_mc.push_back(Facet(t,n,values_list->item(value_id)));
      }
      nbs_of_mc_triangles[value_id]=m_surface_mc.size();
      mc_timer.start();
    }
    mc_timer.stop();
    not_busy();
    mc_total_time = total_time.elapsed();

    // invalidate the display list
    lists_draw_surface_mc_is_valid = false;
    list_draw_marching_cube_is_valid = false;
  }
  CGAL::Bbox_3 bbox(0,0,0,0,0,0);
  for(std::vector<Facet>::const_iterator
        it = m_surface_mc.begin(), end = m_surface_mc.end();
      it != end; ++it)
  {
    bbox = bbox + it->get<0>().bbox();
  }

  m_view_mc = true;
  m_view_surface = false;
  Q_EMIT changed();
  if(!m_surface_mc.empty())
  {
    Q_EMIT new_bounding_box(bbox.xmin(),
                          bbox.ymin(),
                          bbox.zmin(),
                          bbox.xmax(),
                          bbox.ymax(),
                          bbox.zmax());
  }
  status_message(tr("Marching cubes done. %2 facets in %1s (CPU time), total time is %3s.")
                 .arg(mc_timer.time())
                 .arg(m_surface_mc.size())
                 .arg(mc_total_time/1000.));

  save_image_settings(fileinfo.absoluteFilePath());
#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
}

void Volume::display_surface_mesher_result()
{
  if(m_surface.empty() || // Either the surface is not computed.
     m_view_surface) // Or it is computed and displayed, and one want
                     // to recompute it.
  {
    QTime total_time;
    total_time.start();

    values_list->save_values(fileinfo.absoluteFilePath());

    std::size_t nx = m_image.xdim();
    std::size_t ny = m_image.ydim();
    std::size_t nz = m_image.zdim();
    if(nx * ny * nz == 0)
    {
      status_message("No volume loaded.");
      return;
    }

    m_surface.clear();
    sm_timer.reset();
    busy();

    status_message("Surface meshing...");

    sm_timer.start();

    c2t3.clear();
    del.clear();
    Sphere bounding_sphere(m_image.center(),m_image.radius()*m_image.radius());

    Classify_from_isovalue_list classify(values_list);
    Generate_surface_identifiers generate_ids(values_list);

    m_image.set_interpolation(mw->interpolationCheckBox->isChecked());
    if(mw->labellizedRadioButton->isChecked()) {
      std::cerr << "Labellized image\n";
    }
    m_image.set_labellized(mw->labellizedRadioButton->isChecked());
    classify.set_identity(mw->labellizedRadioButton->isChecked());
    generate_ids.set_labellized_image(mw->labellizedRadioButton->isChecked());

    // definition of the surface
    Surface_3 surface(m_image, bounding_sphere, m_relative_precision);
//     Threshold threshold(m_image.isovalue());

    // surface mesh traits class
    typedef CGAL::Surface_mesher::Implicit_surface_oracle_3<Kernel,
      //     typedef CGAL::Surface_mesher::Image_surface_oracle_3<Kernel,
      Surface_3,
      Classify_from_isovalue_list,
      Generate_surface_identifiers> Oracle;
    Oracle oracle(classify, generate_ids);

    if(mw->searchSeedsCheckBox->isChecked())
    {
      typedef std::vector<std::pair<Point, double> > Seeds;
      Seeds seeds;
      {
	std::cerr << "Search seeds...\n";
	std::set<unsigned char> domains;
	search_for_connected_components(std::back_inserter(seeds),
					CGAL::inserter(domains),
					classify);
	std::cerr << "Found " << seeds.size() << " seed(s).\n";

	if(mw->labellizedRadioButton->isChecked() &&
	   values_list->numberOfValues() == 0)
	{
	  Q_FOREACH(unsigned char label, domains) {
	    if(label != 0) {
	      values_list->addValue(label);
	    }
	  }
	}
      }
      std::ofstream seeds_out("seeds.off");
      std::ofstream segments_out("segments.txt");
      seeds_out.precision(18);
      seeds_out << "OFF\n" << seeds.size() << " 0 0\n";
      segments_out.precision(18);
      for(Seeds::const_iterator it = seeds.begin(), end = seeds.end();
	  it != end; ++it)
      {
        seeds_out << it->first << std::endl;
	CGAL::Random_points_on_sphere_3<Point> random_points_on_sphere_3(it->second);
	Oracle::Intersect_3 intersect = oracle.intersect_3_object();
	for(int i = 0; i < 20; ++i)
	{
	  const Point test = it->first + (*random_points_on_sphere_3++ - CGAL::ORIGIN);
	  CGAL::Object o = intersect(surface, Segment_3(it->first, test));
	  if (const Point* intersection = CGAL::object_cast<Point>(&o)) {
            segments_out << "2 " << it->first << " " << *intersection << std::endl;
	    del.insert(*intersection);
          }
	  else
	  {
	    std::cerr <<
	      boost::format("Error. Segment (%1%, %2%) does not intersect the surface! values=(%3%, %4%)\n")
	      % it->first % test
	      % surface(it->first) % surface(test);
	  }
	}
      }
    }
    else {
      oracle.construct_initial_points_object()(surface,
					       CGAL::inserter(c2t3.triangulation()),
					       20);
    }

    std::ofstream points_out("initial-points.off");
    points_out.precision(18);
    points_out << "OFF\n" << c2t3.triangulation().number_of_vertices() << " 0 0\n";
    BOOST_FOREACH(const Tr::Vertex& v,
                  std::make_pair(c2t3.triangulation().vertices_begin(),
                                 c2t3.triangulation().vertices_end()))
    {
      points_out << v.point() << std::endl;
    }

    std::cerr << boost::format("Number of initial points: %1%\n") % del.number_of_vertices();

    // defining meshing criteria
    typedef CGAL::Surface_mesher::Refine_criterion<Tr> Criterion;
    CGAL::Surface_mesher::Curvature_size_criterion<Tr>
      curvature_size_criterion (m_sm_distance);
    CGAL::Surface_mesher::Uniform_size_criterion<Tr>
      uniform_size_criterion (m_sm_radius);
    CGAL::Surface_mesher::Aspect_ratio_criterion<Tr>
      aspect_ratio_criterion (m_sm_angle);
    CGAL::Surface_mesher::Vertices_on_the_same_psc_element_criterion<Tr, Surface_3>
      vertices_on_the_same_psc_element_criterion(surface);

    std::vector<Criterion*> criterion_vector;
    criterion_vector.push_back(&aspect_ratio_criterion);
    criterion_vector.push_back(&uniform_size_criterion);
    criterion_vector.push_back(&curvature_size_criterion);
    if(mw->sameIndexCheckBox->isChecked()) {
      criterion_vector.push_back(&vertices_on_the_same_psc_element_criterion);
      std::cerr << "vertices_on_the_same_psc_element_criterion is activated.\n";
    }

    typedef CGAL::Surface_mesher::Standard_criteria<Criterion> Criteria;
    Criteria criteria(criterion_vector);
    std::cerr << "Surface_mesher... angle=" << m_sm_angle << ", radius= " << m_sm_radius
              << ", distance=" << m_sm_distance << "\n";

    typedef CGAL::Surface_mesher_generator<C2t3,
      Oracle,
      Criteria,
      CGAL::Manifold_tag,
      CGAL_SURFACE_MESHER_VERBOSITY
      >::type Surface_mesher_manifold;

    typedef CGAL::Surface_mesher_generator<C2t3,
      Oracle,
      Criteria,
      CGAL::Non_manifold_tag,
      CGAL_SURFACE_MESHER_VERBOSITY
      >::type Surface_mesher_non_manifold;

    if(mw->manifoldCheckBox->isChecked()) {
      // meshing surface
      std::cerr << "manifold criteria is activated.\n";
//       make_surface_mesh(c2t3, surface, oracle, criteria,
// 			CGAL::Manifold_tag(), 0);
      Surface_mesher_manifold manifold_mesher(c2t3, surface, oracle, criteria);
      manifold_mesher.refine_mesh();
    }
    else {
//       m_view_surface = true;
      Surface_mesher_non_manifold non_manifold_mesher(c2t3, surface, oracle, criteria);
#if 0
      int nb_steps = 0;
//       direct_draw = true;
      non_manifold_mesher.init();
      while(!non_manifold_mesher.is_algorithm_done()) {
	CGAL::Null_mesh_visitor null_visitor;
	non_manifold_mesher.one_step(null_visitor);
	if(++nb_steps % 1000 == 0) {
	  CGAL::Timer timer;
	  std::cerr << "(process events...";
	  timer.start();
	  list_draw_marching_cube_is_valid = false;
	  lists_draw_surface_is_valid = false;
	  for(Tr::Finite_cells_iterator
		cit = del.finite_cells_begin(),
		end = del.finite_cells_end();
	      cit != end; ++cit)
	  {
	    cit->info() = classify(surface(cit->circumcenter()));
	  }
// 	  Q_EMIT changed();
	  qApp->processEvents();
	  timer.stop();
	  std::cerr << timer.time() << " secondes)\n";
	}
      }
#else
      non_manifold_mesher.refine_mesh();
#endif
    }
    sm_timer.stop();
    not_busy();
    direct_draw = false;

    for(Tr::Finite_cells_iterator
	  cit = del.finite_cells_begin(),
	  end = del.finite_cells_end();
	cit != end; ++cit)
    {
      cit->info() = classify(surface(cit->circumcenter()));
    }
    // get output surface
    for(C2t3::Facet_iterator
          fit = c2t3.facets_begin(), end = c2t3.facets_end();
        fit != end; ++fit)
    {
      const Tr::Cell_handle& cell = fit->first;
      const int index = fit->second;

      // here "left" means nothing
      const Point left_circumcenter = cell->circumcenter();
      const Point right_circumcenter = cell->neighbor(index)->circumcenter();

      const Triangle_3 t =
        Triangle_3(cell->vertex(del.vertex_triple_index(index, 0))->point(),
                   cell->vertex(del.vertex_triple_index(index, 1))->point(),
                   cell->vertex(del.vertex_triple_index(index, 2))->point());
      const Vector u = t[1] - t[0];
      const Vector v = t[2] - t[0];
      Vector n = CGAL::cross_product(u,v);
      n = n / std::sqrt(n*n);
      if(mw->labellizedRadioButton->isChecked())
      {
	m_surface.push_back(Facet(t,
				  n,
				  values_list->search((std::max)(surface(left_circumcenter),
								 surface(right_circumcenter)))));
      }
      else {
	m_surface.push_back(Facet(t,n,cell->vertex(del.vertex_triple_index(index, 0))->point().element_index()));
      }
    }

    // invalidate the display list
    lists_draw_surface_is_valid = false;
    sm_total_time = total_time.elapsed();
  }

  CGAL::Bbox_3 bbox(0,0,0,0,0,0);
  for(std::vector<Facet>::const_iterator
        it = m_surface.begin(), end = m_surface.end();
      it != end; ++it)
  {
    bbox = bbox + it->get<0>().bbox();
  }

  // toggle visualization
  m_view_mc = false;
  m_view_surface = true;
  Q_EMIT changed();
  if(!m_surface.empty())
  {
    Q_EMIT new_bounding_box(bbox.xmin(),
                          bbox.ymin(),
                          bbox.zmin(),
                          bbox.xmax(),
                          bbox.ymax(),
                          bbox.zmax());
  }
  status_message(tr("Surface meshing done. %1 facets in %2s (CPU time), total time is %3s.")
                 .arg(m_surface.size())
                 .arg(sm_timer.time())
                 .arg(sm_total_time/1000.));
  save_image_settings(fileinfo.absoluteFilePath());
}

void Volume::draw()
{
  float	ambient[]  =   { 0.25f,
                         0.20725f,
                         0.20725f,
                         0.922f };
  float	diffuse[]  =   { 1.0f,
                         0.829f,
                         0.829f,
                         0.922f };

  float	specular[]  = {  0.296648f,
                         0.296648f,
                         0.296648f,
                         0.522f };

  float	emission[]  = {  0.3f,
                         0.3f,
                         0.3f,
                         1.0f };
  float shininess[] = {  11.264f };

  // apply
  ::glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT,   ambient);
  ::glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE,   diffuse);
  ::glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR,  specular);
  ::glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, shininess);
  ::glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION,  emission);

  ::glEnable(GL_LINE_SMOOTH);

  if(two_sides)
    ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  else
    ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); // default

  // draw surface mesh
  if(m_view_surface)
  {
    ::glEnable(GL_LIGHTING);
    ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    ::glColor3f(0.2f, 0.2f, 1.f);
    ::glEnable(GL_POLYGON_OFFSET_FILL);
    ::glPolygonOffset(3.0f,-3.0f);
    gl_draw_surface();

    if(draw_triangles_edges)
    {
      ::glDisable(GL_LIGHTING);
      ::glLineWidth(1.);
      ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
      ::glColor3ub(0,0,0);
      ::glDisable(GL_POLYGON_OFFSET_FILL);
      gl_draw_surface();
    }
  }

#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
  // draw MC surface mesh
  if(m_view_mc)
  {
    ::glEnable(GL_LIGHTING);
    ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    ::glColor3f(0.2f, 0.2f, 1.f);
    ::glEnable(GL_POLYGON_OFFSET_FILL);
    ::glPolygonOffset(3.0f,-3.0f);
    gl_draw_surface_mc();

    if(draw_triangles_edges)
    {
      ::glDisable(GL_LIGHTING);
      ::glLineWidth(1.);
      ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
      ::glColor3ub(0,0,0);
      ::glDisable(GL_POLYGON_OFFSET_FILL);
      gl_draw_surface_mc();
    }
  }
#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE

  if(show_bbox) {
    ::glDisable(GL_LIGHTING);
    m_image.gl_draw_bbox(3.0f,0,0,0);
  }

  if(!m_view_mc && m_draw_triangulation)
  {
    // draw the triangualtion
    mw->viewer->qglColor(m_triangulation_color);
    ::glLineWidth(1.0);
    ::glBegin(GL_LINES);
    for(Tr::Finite_edges_iterator
          eit = del.finite_edges_begin(),
          end = del.finite_edges_end();
        eit != end; ++eit)
    {
      const Point p1 = eit->first->vertex(eit->second)->point();
      const Point p2 = eit->first->vertex(eit->third)->point();
      ::glVertex3d(p1.x(),p1.y(),p1.z());
      ::glVertex3d(p2.x(),p2.y(),p2.z());
    }
    ::glEnd();
  }
}

void Volume::set_radius_bound(double d)
{
  m_sm_radius = FT(d);
  changed_parameters();
}

void Volume::set_distance_bound(double d)
{
  m_sm_distance = FT(d);
  changed_parameters();
}

#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
void Volume::gl_draw_surface_mc()
{
  if(use_gouraud)
  {
    gl_draw_marchingcube();
    return;
  }

  if(lists_draw_surface_mc_is_valid)
  {
    for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i )
    {
      if(values_list->enabled(i))
      {
        mw->viewer->qglColor(values_list->color(i));
        ::glCallList(lists_draw_surface_mc[i]);
      }
    }
  }
  else
  {
    lists_draw_surface_mc.resize(values_list->numberOfValues(), 0);
    for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i )
    {
      if(!lists_draw_surface_mc[i])
      {
        lists_draw_surface_mc[i] = ::glGenLists(1);
      }

      std::cerr << boost::format("(Re-)Generating list #%1% for marching cube surface #%2%"
                                 " in gl_draw_surface(), ()\n")
        % lists_draw_surface_mc[i]
        % i;

      mw->viewer->qglColor(values_list->color(i));

      if(lists_draw_surface_mc[i])             // If
        ::glNewList(lists_draw_surface_mc[i],  // lists_draw_surface[i]==0 then something
                    values_list->enabled(i) // got wrong in the list generation.
                    ? GL_COMPILE_AND_EXECUTE
                    : GL_COMPILE);

      gl_draw_surface(m_surface_mc.begin(),
                      m_surface_mc.end(),
                      values_list->item(i));

      if(lists_draw_surface_mc[i]) // If lists_draw_surface[i]==0 then
      {                            // something got wrong in the list
        ::glEndList();             // generation.
      }
    }
    lists_draw_surface_mc_is_valid = (::glGetError() == GL_NO_ERROR);
  }
}
#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE

void Volume::gl_draw_surface()
{
//   if(mw->labellizedRadioButton->isChecked()) {
//     mw->viewer->qglColor(::Qt::blue);
//     gl_draw_surface(m_surface.begin(),
// 		    m_surface.end(),
// 		    0);
//   }
//   else
  if(direct_draw) {
    ::glBegin(GL_TRIANGLES);
    unsigned int counter = 0;
    for(Tr::Finite_cells_iterator
	  cit = del.finite_cells_begin(), end = del.finite_cells_end();
	cit != end; ++cit)
    {
      for(int facet_index = 0; facet_index < 4; ++facet_index)
      {
	const Tr::Cell_handle& facet_cell = cit;
	if(c2t3.face_status(facet_cell, facet_index) == C2t3::NOT_IN_COMPLEX) {
	  continue;
	}
	const Point& a = facet_cell->vertex(del.vertex_triple_index(facet_index, 0))->point();
	const Point& b = facet_cell->vertex(del.vertex_triple_index(facet_index, 1))->point();
	const Point& c = facet_cell->vertex(del.vertex_triple_index(facet_index, 2))->point();
	Vector n = CGAL::cross_product(b-a,c-a);
	n = n / std::sqrt(n*n); // unit normal
	if(m_inverse_normals) {
	  ::glNormal3d(-n.x(),-n.y(),-n.z());
	} else {
	  ::glNormal3d(n.x(),n.y(),n.z());
	}
	mw->viewer->qglColor(values_list->color(values_list->search(facet_cell->info())));
	::glVertex3d(a.x(),a.y(),a.z());
	::glVertex3d(b.x(),b.y(),b.z());
	::glVertex3d(c.x(),c.y(),c.z());
	++counter;
      }
      ::glEnd();
    }
    return;
  }
  if(!direct_draw && lists_draw_surface_is_valid)
  {
    for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i )
    {
      if(values_list->enabled(i))
      {
        mw->viewer->qglColor(values_list->color(i));
        ::glCallList(lists_draw_surface[i]);
      }
    }
  }
  else
  {
    lists_draw_surface.resize(values_list->numberOfValues(), 0);
    for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i )
    {
      if(!lists_draw_surface[i])
      {
        lists_draw_surface[i] = ::glGenLists(1);
      }

      std::cerr << boost::format("(Re-)Generating list #%1% for surface #%2%"
                                 " in gl_draw_surface(), ()\n")
        % lists_draw_surface[i]
        % i;

      mw->viewer->qglColor(values_list->color(i));

      if(!direct_draw && lists_draw_surface[i]) // If
        ::glNewList(lists_draw_surface[i],      // lists_draw_surface[i]==0
                    values_list->enabled(i)     // then something got wrong
                    ? GL_COMPILE_AND_EXECUTE    // in the list generation.
                    : GL_COMPILE);

      if(!mw->labellizedRadioButton->isChecked())
      {
	gl_draw_surface(m_surface.begin(),
			m_surface.end(),
			values_list->item(i));
      }
      else
      {
	const unsigned char volume_index = values_list->value(i);

	::glBegin(GL_TRIANGLES);
	unsigned int counter = 0;
	for(C2t3::Facet_iterator
	      fit = c2t3.facets_begin(), end = c2t3.facets_end();
	    fit != end; ++fit)
	{
	  Tr::Cell_handle facet_cell = fit->first;
	  int facet_index = fit->second;
	  Tr::Cell_handle opposite_cell = facet_cell->neighbor(facet_index);
	  int opposite_index = opposite_cell->index(facet_cell);

	  if( facet_cell->info() != volume_index ) {
	    if( opposite_cell->info() == volume_index ) {
	      std::swap(facet_cell, opposite_cell);
	      std::swap(facet_index, opposite_index);
	    }
	    else
	      continue; // go to next facet
	  }
	  const Point& a = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 0))->point();
	  const Point& b = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 1))->point();
	  const Point& c = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 2))->point();
	  Vector n = CGAL::cross_product(b-a,c-a);
	  n = n / std::sqrt(n*n); // unit normal
	  if(m_inverse_normals) {
	    ::glNormal3d(-n.x(),-n.y(),-n.z());
	  } else {
	    ::glNormal3d(n.x(),n.y(),n.z());
	  }
	  ::glVertex3d(a.x(),a.y(),a.z());
	  ::glVertex3d(b.x(),b.y(),b.z());
	  ::glVertex3d(c.x(),c.y(),c.z());
	  ++counter;
	}
	::glEnd();
	std::cerr << boost::format("(c2t3) number of facets: %1%\n")
	  % counter;
      }

      if(!direct_draw && lists_draw_surface[i])
	                        // If lists_draw_surface[i]==0 then
      {                         // something got wrong in the list
        ::glEndList();          // generation.
      }
    }
    lists_draw_surface_is_valid = (::glGetError() == GL_NO_ERROR);
  }
}

template <typename Iterator>
void Volume::gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem* i)
{
  ::glBegin(GL_TRIANGLES);
  unsigned int counter = 0;
  for(Iterator it = begin; it != end; ++it)
  {
    const Facet& f = *it;

    if(f.get<2>() != i) continue;

    const Vector& n = f.get<1>();

    if(m_inverse_normals)
      ::glNormal3d(-n.x(),-n.y(),-n.z());
    else
      ::glNormal3d(n.x(),n.y(),n.z());

    const Triangle_3& t = f.get<0>();
    const Point& a = t[0];
    const Point& b = t[1];
    const Point& c = t[2];

    ::glVertex3d(a.x(),a.y(),a.z());
    ::glVertex3d(b.x(),b.y(),b.z());
    ::glVertex3d(c.x(),c.y(),c.z());
    ++counter;
  }
  ::glEnd();
  std::cerr << boost::format("number of facets: %1%\n")
    % counter;
}

void Volume::changed_parameters()
{
  m_surface.clear();
#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
  m_surface_mc.clear();
#endif
  list_draw_marching_cube_is_valid = false;
  lists_draw_surface_is_valid = false;
  c2t3.clear();
  del.clear();
  m_view_mc = m_view_surface = false;
  Q_EMIT changed();
}

#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE
void Volume::gl_draw_one_marching_cube_vertex(int i)
{
  if(!m_inverse_normals)
    glArrayElement(i);
  else
  {
    const Vertex* const vertex = mc.vert(i);
    ::glNormal3d(-vertex->nx, -vertex->ny, -vertex->nz);
    ::glVertex3d(vertex->x, vertex->y, vertex->z);
  }
}

void Volume::gl_draw_marchingcube()
{
  if(list_draw_marching_cube_is_valid)
    ::glCallList(list_draw_marching_cube);
  else
  {
    if(!list_draw_marching_cube)
      list_draw_marching_cube = ::glGenLists(1);
    std::cerr << boost::format("(Re-)Generating list #%1% for"
                               " gl_draw_marchingcube()\n")
      % list_draw_marching_cube;

    if(list_draw_marching_cube)          // If list_draw_marching_cube==0 then
    ::glNewList(list_draw_marching_cube, // something got wrong in the list
                GL_COMPILE_AND_EXECUTE); // generation.

    ::glVertexPointer(3, GL_DOUBLE, sizeof(Vertex), mc.vertices());
    ::glNormalPointer(GL_DOUBLE, sizeof(Vertex), &(mc.vertices()->nx));
    ::glEnableClientState(GL_VERTEX_ARRAY);

    // because of that conditionnal, the display list has to be
    // reconstructed each time m_inverse_normals is toggled.
    if(!m_inverse_normals)
      ::glEnableClientState(GL_NORMAL_ARRAY);

    for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i)
    {
      const int begin = i == 0 ? 0 : nbs_of_mc_triangles[i-1];
      const int end = nbs_of_mc_triangles[i];
      mw->viewer->qglColor(values_list->color(i));
      ::glBegin(GL_TRIANGLES);
      for(int i = begin; i < end; ++i)
      {
        const MC_Triangle* const trig = mc.trig(i);
        gl_draw_one_marching_cube_vertex(trig->v1);
        gl_draw_one_marching_cube_vertex(trig->v2);
        gl_draw_one_marching_cube_vertex(trig->v3);
      }
      ::glEnd();
    }
    if(list_draw_marching_cube > 0) // If list_draw_marching_cube==0 then
    {                               // something got wrong in the list
      ::glEndList();                // generation.
      list_draw_marching_cube_is_valid = (::glGetError() == GL_NO_ERROR);
    }
    if(!list_draw_marching_cube_is_valid)
    {
     CGAL::Qt::opengl_check_errors();
    }
  }
}
#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE

void Volume::save_image_settings(QString filename)
{
  QSettings settings;
  settings.beginGroup(QUrl::toPercentEncoding(filename));
  settings.setValue("labellized", mw->labellizedRadioButton->isChecked());
  settings.endGroup();
}

void Volume::load_image_settings(QString filename)
{
  QSettings settings;
  settings.beginGroup(QUrl::toPercentEncoding(filename));
  mw->labellizedRadioButton->setChecked(settings.value("labellized").toBool());
  settings.endGroup();
}

void Volume::labellizedToogled(bool toggled)
{
  if(toggled) {
    values_list->setHeaderTitle(tr("Label"));
  }
  else {
    values_list->setHeaderTitle(tr("Iso-Value"));
  }
}


text:
package core

import akka.actor._
import akka.pattern.{ask, pipe}
import akka.util.Timeout
import core.ResultReceivingActor._
import file.CsvFileActorMessages.ReadIndexMessage
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

object ResultReceivingActor {
  case class RequestResultMessage(v1: Int)
}

class ResultReceivingActor(interimResultsFileActor: ActorRef) extends Actor {

  implicit val timeout = Timeout(2.seconds)

  def receive: Receive = {
    case RequestResultMessage(v1) => {
      (interimResultsFileActor ? ReadIndexMessage(v1)).mapTo[Option[Int]].map {
        case Some(fv1) if fv1 > 10 => Some(fv1 - 10)
        case Some(fv1) => Some(fv1)
        case _ => None
      } pipeTo sender
    }
  }
}


text:
package examples;

import ev3dev.actuators.lego.motors.EV3LargeRegulatedMotor;
import ev3dev.sensors.Battery;
import lejos.hardware.port.MotorPort;
import lejos.utility.Delay;

public class MyFirstRobot {

    public static void main(final String[] args){

        System.out.println("Creating Motor A & B");
        final EV3LargeRegulatedMotor motorLeft = new EV3LargeRegulatedMotor(MotorPort.A);
        final EV3LargeRegulatedMotor motorRight = new EV3LargeRegulatedMotor(MotorPort.B);

        //To Stop the motor in case of pkill java for example
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
                System.out.println("Emergency Stop");
                motorLeft.stop();
                motorRight.stop();
            }
        }));

        System.out.println("Defining the Stop mode");
        motorLeft.brake();
        motorRight.brake();

        System.out.println("Defining motor speed");
        final int motorSpeed = 200;
        motorLeft.setSpeed(motorSpeed);
        motorRight.setSpeed(motorSpeed);

        System.out.println("Go Forward with the motors");
        motorLeft.forward();
        motorRight.forward();

        Delay.msDelay(2000);

        System.out.println("Stop motors");
        motorLeft.stop();
        motorRight.stop();

        System.out.println("Go Backward with the motors");
        motorLeft.backward();
        motorRight.backward();

        Delay.msDelay(2000);

        System.out.println("Stop motors");
        motorLeft.stop();
        motorRight.stop();

        System.out.println("Checking Battery");
        System.out.println("Votage: " + Battery.getInstance().getVoltage());

        System.exit(0);
    }
}


text:
//***********************************************************************//
//																		 //
//		- "Talk to me like I'm a 3 year old!" Programming Lessons -		 //
//                                                                       //
//		$Author:		Ben Humphrey	digiben@gametutorials.com		 //
//																		 //
//		$Program:		Questions										 //
//																		 //
//		$Description:	Asks/Answers questions using if/else statements. //
//																		 //
//***********************************************************************//

// This tutorial shows you how to use "if statements" and "else statements"
// to control what happens in your program.  In this example, we have the user
// input their age, and then depending on how old they are, we print out a
// specialized message.  You will use if and else statements in pretty much
// every program you will ever create, especially if you allow the user to
// do things and interact with your program.  Look below to see how we use them.

#include <iostream>							// This line of code is necessary to include all the C++ standard functions\classes definitions
using namespace std;						// Set our namespace to standard (don't stress on this right now)

int main()									// This creates our function main()
{											// This starts the main function
	int age=0;								// Initialize a integer variable for the age

	cout << "How old are you? ";			// Print to the screen a questions about the users age.

	cin >> age;								// Read in the answer after the user hits return.

											// NOW!  Get ready for IF and ELSE statements! Muhahaha!
	if(age > 20)							// This is an IF statement.  This is simply saying:
	{										// "If age is greater than 20", then...
											// Print this message
		cout << "You're over 20 huh?" << endl;
	}										// End the if statement

	if(age > 30)							// This checks if the age entered was over 30,
		cout << "You're over 30!?" << endl;	// Print this message

											// Now you might have noticed that there was no "{" "}" brackets.
											// Well, you don't HAVE to use brackets if there is only one line
											// after the condition, either it be a while, a for, or an if/else....
											// The fact is that it's a good habit to get into and makes your
											// code more readable (which is good!)  You also tend to find yourself
											// adding things inside your statements (for, while, if), so you might as
											// well just put it there for the future, just a coding preference I guess.

											// If the user typed 35 as their age, the program would print out both messages above.
											// But if they entered something like 25, it would only print the first one.

	if(age < 20) {							// Here is another coding style...  people who put their "{" after the conditional statement.
		cout << "You're a young'n!" << endl;// This doesn't do anything different, it's just that some people prefer it.
	}										// There are some languages that REQUIRE it, but C/C++ is VERY flexible where there are
											// very few REQUIRED syntax.  Actually, you could even do this and it would work:
											// "if(age < 20) cout << "You're a young'n!" << endl;"
											// You don't even need a new line OR brackets (if it's only one line after).
											// This is why ";" semicolons are important.  It let's the compiler know to
											// go on to the next statement.  you can do things like this:
											// "age++; age--; age = age;"
											// This adds 1 to age, subtracts one to age, then assigns age to age...
											// which does absolutely nothing, but you see my point.
											// You don't need to skip a line, just use semicolons.
											// it all boils down to readable code.  That is what is important.

	if(age < 20 && age > 12)				// Here is something new.  The "&&" means "and".
	{										// So the statement is saying, "if ( age is less than 20 AND greater than 12)"
		cout << "Being in your teens can be tough..." << endl;
	}										// cout the message
											// You will use this type of expression a lot.  There is also :
											// "!=" -> does not equal    and    "||" -> or
											// So instead of checking if both things are true, you can check if one or the other are true
											// by using "||"   the OR operator.
											// If you are familiar with the binary operators, "&", and "|" ....
											// These are similar, but different.  "&&" and "||" check conditions between 2 statements.
											// if the user is a teenager, the message would have printed to the screen.

	if(age == 100)							// This checks if "age equals 100".  This is different from "age = 100"
		cout << "WOW!  What's your secret!?" << endl;
											// "age == 100" checks to see if the value of age is 100, while "age = 100" assigns the value 100 to the variable age.

	if(age > 50)							// Here is another usage of IF statements.
		cout << "Life after 50 can be great!" << endl;
	else									// If age isn't greater than 50, print the other message below
		cout << "You've still got a LONG way to go..." << endl;
											// Look below for an if/else statement explanation

	return 0;								// Return with zero problems
}											// This ends the main function (program is done)

// This is what we call IF/ELSE statements.
// "	if( <The statement here is true> )	  "
// "		<do this>						  "
// "	else								  "
// "		<do this instead>                 "

// You might be wondering by now about the spacing after conditional statements.
// It all falls back to code readability.  It's not fun to look at un-formatted code.
// If you ever want people to help you (which you WILL!) you have to comment and
// indent your code, or else they won't even try.
// Remember, you CAN and probably should use { } 's.

//		if (etc)
//		{
//			<do this>
//		}
//		else
//		{
//			<do this>
//		}

// It's so much easier to understand.  Even if you only have one line after each statement.

// © 2000-2005 GameTutorials