+ processor.reset (new PluginInsert(_session, node));
+
+ } else if (prop->value() == "port") {
+
+ processor.reset (new PortInsert (_session, _mute_master, node));
+
+ } else if (prop->value() == "send") {
+
+ processor.reset (new Send (_session, _mute_master, node));
+
+ } else if (prop->value() == "meter") {
+
+ if (_meter) {
+ if (_meter->set_state (node, Stateful::loading_state_version)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ _meter.reset (new PeakMeter (_session, node));
+ processor = _meter;
+
+ } else if (prop->value() == "amp") {
+
+ /* amp always exists */
+
+ processor = _amp;
+ if (processor->set_state (node, Stateful::loading_state_version)) {
+ return false;
+ } else {
+ /* never any reason to add it */
+ return true;
+ }
+
+ } else if (prop->value() == "intsend") {
+
+ processor.reset (new InternalSend (_session, _mute_master, node));
+
+ } else if (prop->value() == "intreturn") {
+
+ if (_intreturn) {
+ if (_intreturn->set_state (node, Stateful::loading_state_version)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ _intreturn.reset (new InternalReturn (_session, node));
+ processor = _intreturn;
+
+ } else if (prop->value() == "main-outs") {
+
+ if (_main_outs) {
+ if (_main_outs->set_state (node, Stateful::loading_state_version)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ _main_outs.reset (new Delivery (_session, _output, _mute_master, node));
+ processor = _main_outs;
+
+ } else {
+ error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
+ return false;
+ }
+
+ if (iter == _processors.end() && processor->visible() && !_processors.empty()) {
+ /* check for invisible processors stacked at the end and leave them there */
+ ProcessorList::iterator p;
+ p = _processors.end();
+ --p;
+ while (!(*p)->visible() && p != _processors.begin()) {
+ --p;
+ }
+ ++p;
+ iter = p;
+ }
+
+ return (add_processor (processor, iter) == 0);
+
+ } else {
+ error << _("Processor XML node has no type property") << endmsg;
+ return false;
+ }
+ }
+
+ catch (failed_constructor &err) {
+ warning << _("processor could not be created. Ignored.") << endmsg;
+ return false;
+ }
+}
+
+
+bool
+Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorList::iterator iter)
+{
+ const XMLProperty *prop;
+
+ try {
+ boost::shared_ptr<Processor> processor;
+
+ if (node.name() == "Insert") {
+
+ if ((prop = node.property ("type")) != 0) {
+
+ if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
+ prop->value() == "lv2" ||
+ prop->value() == "vst" ||
+ prop->value() == "audiounit") {
+
+ processor.reset (new PluginInsert (_session, node));
+
+ } else {
+
+ processor.reset (new PortInsert (_session, _mute_master, node));
+ }
+
+ }
+
+ } else if (node.name() == "Send") {
+
+ processor.reset (new Send (_session, _mute_master, node, version));
+
+ } else {
+
+ error << string_compose(_("unknown Processor type \"%1\"; ignored"), node.name()) << endmsg;
+ return false;
+ }
+
+ if (iter == _processors.end() && processor->visible() && !_processors.empty()) {
+ /* check for invisible processors stacked at the end and leave them there */
+ ProcessorList::iterator p;
+ p = _processors.end();
+ --p;
+ while (!(*p)->visible() && p != _processors.begin()) {
+ --p;
+ }
+ ++p;
+ iter = p;
+ }
+
+ return (add_processor (processor, iter) == 0);
+ }
+
+ catch (failed_constructor &err) {
+ warning << _("processor could not be created. Ignored.") << endmsg;
+ return false;
+ }
+}
+
+int
+Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err)
+{
+ ProcessorList::iterator loc;
+
+ if (before) {
+ loc = find(_processors.begin(), _processors.end(), before);
+ } else {
+ /* nothing specified - at end but before main outs */
+ loc = find (_processors.begin(), _processors.end(), _main_outs);
+ }
+
+ return add_processors (others, loc, err);
+}
+
+int
+Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter, ProcessorStreams* err)
+{
+ /* NOTE: this is intended to be used ONLY when copying
+ processors from another Route. Hence the subtle
+ differences between this and ::add_processor()
+ */
+
+ ChanCount old_pms = processor_max_streams;
+
+ if (!_session.engine().connected()) {
+ return 1;
+ }
+
+ if (others.empty()) {
+ return 0;
+ }
+
+ {
+ Glib::RWLock::WriterLock lm (_processor_lock);
+ ProcessorList::iterator existing_end = _processors.end();
+ --existing_end;
+
+ ChanCount potential_max_streams = ChanCount::max (_input->n_ports(), _output->n_ports());
+
+ for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
+
+ // Ensure meter only appears in the list once
+ if (*i == _meter) {
+ ProcessorList::iterator m = find(_processors.begin(), _processors.end(), *i);
+ if (m != _processors.end()) {
+ _processors.erase(m);
+ }
+ }
+
+ boost::shared_ptr<PluginInsert> pi;
+
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {