Please complete the code given below. 
/**
 * 
 */
package com.gint.app.bisis4.client.editor.inventar;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FocusTraversalPolicy;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout;
import com.gint.app.bisis4.client.BisisApp;
import com.gint.app.bisis4.client.editor.Messages;
import com.gint.app.bisis4.format.HoldingsDataCoders;
import com.gint.app.bisis4.format.UValidatorException;
import com.gint.app.bisis4.records.Primerak;
/**
 * @author Bojana
 *
 */
public class RaspodelaFrame extends JInternalFrame {
	
	private JTable raspodelaTable;	
	private JScrollPane raspodelaScrollPane;
	
	private JPanel raspodelaButtonsPanel;	
	private JButton sacuvajButton;
	private JButton odustaniButton;
	
	private JTextField brojPrimTxtFld;
	private JTextField preostaloTxtFld;
	private CodedValuePanel odeljenjePanel;
	private CodedValuePanel invKnjPanel;
	private CodedValuePanel podlokacijaPanel;
	
	private JSpinner raspodelaSpinner;
	private JButton dodajButton;
	
	private InventarPanel inventarPanel;	
	private RaspodelaTableModel raspodelaTableModel;
	
  private boolean monograph = false;
	
	
	public RaspodelaFrame(InventarPanel mp) {
    super("Raspodela primeraka", true, true, false, false);
    this.monograph = mp instanceof MonographInventarPanel;
    if(!monograph) setTitle("Raspodela godina");
		
		this.inventarPanel = mp;
		this.setSize(new Dimension(800,400));
		create();		
	}
	
	private void create(){		
		raspodelaTable = new JTable();
		brojPrimTxtFld = new JTextField();
		preostaloTxtFld = new JTextField();
		dodajButton = new JButton(new ImageIcon(RaspodelaFrame.class
				.getResource("/com/gint/app/bisis4/client/images/Check16.png")));
		preostaloTxtFld.setEditable(false);
		preostaloTxtFld.setFocusable(false);    
		odeljenjePanel = new CodedValuePanel(HoldingsDataCoders.ODELJENJE_CODER,null);
		odeljenjePanel.setDefaultOdeljenje();
		invKnjPanel = new CodedValuePanel(HoldingsDataCoders.INVENTARNAKNJIGA_CODER,null);
		podlokacijaPanel = new CodedValuePanel(HoldingsDataCoders.PODLOKACIJA_CODER, null);
		raspodelaSpinner = new JSpinner();		
		raspodelaSpinner.setValue(new Integer(1));
		SpinnerNumberModel spinnerModel = new SpinnerNumberModel(0,0,1000,1);
		raspodelaSpinner.setModel(spinnerModel);
		raspodelaSpinner.setPreferredSize(new Dimension(40,20));
		
		//raspodelaSpinner.set
		
		
		raspodelaTableModel = new RaspodelaTableModel(this);
		raspodelaTable.setModel(raspodelaTableModel);		
		raspodelaTable.doLayout();
		raspodelaScrollPane = new JScrollPane(raspodelaTable);
		
		raspodelaButtonsPanel = new JPanel();
		sacuvajButton = new JButton("Raspodeli");
		sacuvajButton.setIcon(new ImageIcon(getClass().getResource(
        "/com/gint/app/bisis4/client/images/ok.gif")));
		sacuvajButton.setEnabled(false);
		odustaniButton = new JButton("Odustani");
		odustaniButton.setIcon(new ImageIcon(getClass().getResource(
        "/com/gint/app/bisis4/client/images/remove.gif")));
		raspodelaButtonsPanel.setLayout(new GridBagLayout());
		GridBagConstraints cB = new GridBagConstraints();
		cB.gridx = 0;
		cB.gridy = 0;
		cB.weightx = 0.1;
		raspodelaButtonsPanel.add(sacuvajButton,cB);
		initialize();
		
		MigLayout layout = new MigLayout("","[][]20[]","[][]30[]0[]10[]0[]10[][]");
		setLayout(layout);
		
		add(new JLabel("Broj knjiga za raspodelu:"),"align right");		
		add(brojPrimTxtFld,"wrap, width :30: ");		
		add(new JLabel("Preostalo:"),"align right");		
		add(preostaloTxtFld,"wrap, width :30:");
	
		add(new JLabel("Odeljenje:"),"cell 0 2 2 1");
		add(odeljenjePanel,"cell 0 3 2 1");
		add(new JLabel("Inventarna knjiga:"),"cell 0 4 2 1");
		add(invKnjPanel,   "cell 0 5 2 1");
		add(new JLabel("Podlokacija:"),"cell 0 6 2 1");
		add(podlokacijaPanel,   "cell 0 7 2 1");
		
		JPanel brPrim = new JPanel();
		brPrim.setLayout(new MigLayout());
		brPrim.add(new JLabel("Broj primeraka:"));
		brPrim.add(raspodelaSpinner,"growy");
		brPrim.add(dodajButton);		
		add(brPrim,"cell 0 8 2 1");		
		add(raspodelaScrollPane,"cell 2 0 1 7, grow");		
		JPanel buttonsPanel = new JPanel();		
		buttonsPanel.add(sacuvajButton);
		buttonsPanel.add(odustaniButton);
		add(buttonsPanel,"cell 2 9 1 1, align right");
    
    RaspodelaFocusTraversalPolicy policy = new RaspodelaFocusTraversalPolicy();
    setFocusTraversalPolicy(policy);
		
		
		
		//actions
		brojPrimTxtFld.addFocusListener(new FocusAdapter(){
			public void focusLost(FocusEvent e) {
				handleSetPreostalo();
				
			}			
		});
		
		dodajButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				handleAddPrimerak();			
			}
			
		});
		
		ListSelectionModel lSelModel = raspodelaTable.getSelectionModel();
		lSelModel.addListSelectionListener(new ListSelectionListener(){
			public void valueChanged(ListSelectionEvent e) {				
					handleLoadPrimerak();				
			}			
		});
		
		
		raspodelaTable.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent e) {
				handleKeys(e);
			}			
		});		
		
		sacuvajButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				handleRaspodeli();				
			}			
		});	
		
		odustaniButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				handleClose();				
			}			
		});
	}
	
	private void initialize(){
		brojPrimTxtFld.setText("0");
	}
	
	private void handleAddPrimerak() {	
		Primerak primerak = ((MonographInventarPanel)inventarPanel).getPrimerakFromForm();
		try {
			if (odeljenjePanel.getCode().equals("") || odeljenjePanel.getCode().equals("")) 
				throw new RaspodelaException("Nisu uneti svi podaci za raspodelu!");
			primerak.setOdeljenje(odeljenjePanel.getCode());


Please complete the code given below. 
#region License
// Copyright (c) 2013, ClearCanvas Inc.
// All rights reserved.
// http://www.clearcanvas.ca
//
// This file is part of the ClearCanvas RIS/PACS open source project.
//
// The ClearCanvas RIS/PACS open source project is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// The ClearCanvas RIS/PACS open source project is distributed in the hope that it
// will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// the ClearCanvas RIS/PACS open source project.  If not, see
// <http://www.gnu.org/licenses/>.
#endregion
// This file is auto-generated by the ClearCanvas.Model.SqlServer.CodeGenerator project.
namespace ClearCanvas.ImageServer.Model.EntityBrokers
{
    using System;
    using System.Xml;
    using ClearCanvas.Enterprise.Core;
    using ClearCanvas.ImageServer.Enterprise;
    public partial class WorkQueueSelectCriteria : EntitySelectCriteria
    {
        public WorkQueueSelectCriteria()
        : base("WorkQueue")
        {}
        public WorkQueueSelectCriteria(WorkQueueSelectCriteria other)
        : base(other)
        {}
        public override object Clone()
        {
            return new WorkQueueSelectCriteria(this);
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="ServerPartitionGUID")]
        public ISearchCondition<ServerEntityKey> ServerPartitionKey
        {
            get
            {
              if (!SubCriteria.ContainsKey("ServerPartitionKey"))
              {
                 SubCriteria["ServerPartitionKey"] = new SearchCondition<ServerEntityKey>("ServerPartitionKey");
              }
              return (ISearchCondition<ServerEntityKey>)SubCriteria["ServerPartitionKey"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="StudyStorageGUID")]
        public ISearchCondition<ServerEntityKey> StudyStorageKey
        {
            get
            {
              if (!SubCriteria.ContainsKey("StudyStorageKey"))
              {
                 SubCriteria["StudyStorageKey"] = new SearchCondition<ServerEntityKey>("StudyStorageKey");
              }
              return (ISearchCondition<ServerEntityKey>)SubCriteria["StudyStorageKey"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="WorkQueueTypeEnum")]
        public ISearchCondition<WorkQueueTypeEnum> WorkQueueTypeEnum
        {
            get
            {
              if (!SubCriteria.ContainsKey("WorkQueueTypeEnum"))
              {
                 SubCriteria["WorkQueueTypeEnum"] = new SearchCondition<WorkQueueTypeEnum>("WorkQueueTypeEnum");
              }
              return (ISearchCondition<WorkQueueTypeEnum>)SubCriteria["WorkQueueTypeEnum"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="WorkQueueStatusEnum")]
        public ISearchCondition<WorkQueueStatusEnum> WorkQueueStatusEnum
        {
            get
            {
              if (!SubCriteria.ContainsKey("WorkQueueStatusEnum"))
              {
                 SubCriteria["WorkQueueStatusEnum"] = new SearchCondition<WorkQueueStatusEnum>("WorkQueueStatusEnum");
              }
              return (ISearchCondition<WorkQueueStatusEnum>)SubCriteria["WorkQueueStatusEnum"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="WorkQueuePriorityEnum")]
        public ISearchCondition<WorkQueuePriorityEnum> WorkQueuePriorityEnum
        {
            get
            {
              if (!SubCriteria.ContainsKey("WorkQueuePriorityEnum"))
              {
                 SubCriteria["WorkQueuePriorityEnum"] = new SearchCondition<WorkQueuePriorityEnum>("WorkQueuePriorityEnum");
              }
              return (ISearchCondition<WorkQueuePriorityEnum>)SubCriteria["WorkQueuePriorityEnum"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="FailureCount")]
        public ISearchCondition<Int32> FailureCount
        {
            get
            {
              if (!SubCriteria.ContainsKey("FailureCount"))
              {
                 SubCriteria["FailureCount"] = new SearchCondition<Int32>("FailureCount");
              }
              return (ISearchCondition<Int32>)SubCriteria["FailureCount"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="ScheduledTime")]
        public ISearchCondition<DateTime> ScheduledTime
        {
            get
            {
              if (!SubCriteria.ContainsKey("ScheduledTime"))
              {
                 SubCriteria["ScheduledTime"] = new SearchCondition<DateTime>("ScheduledTime");
              }
              return (ISearchCondition<DateTime>)SubCriteria["ScheduledTime"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="InsertTime")]
        public ISearchCondition<DateTime> InsertTime
        {
            get
            {
              if (!SubCriteria.ContainsKey("InsertTime"))
              {
                 SubCriteria["InsertTime"] = new SearchCondition<DateTime>("InsertTime");
              }
              return (ISearchCondition<DateTime>)SubCriteria["InsertTime"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="LastUpdatedTime")]
        public ISearchCondition<DateTime?> LastUpdatedTime
        {
            get
            {
              if (!SubCriteria.ContainsKey("LastUpdatedTime"))
              {
                 SubCriteria["LastUpdatedTime"] = new SearchCondition<DateTime?>("LastUpdatedTime");
              }
              return (ISearchCondition<DateTime?>)SubCriteria["LastUpdatedTime"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="FailureDescription")]
        public ISearchCondition<String> FailureDescription
        {
            get
            {
              if (!SubCriteria.ContainsKey("FailureDescription"))
              {
                 SubCriteria["FailureDescription"] = new SearchCondition<String>("FailureDescription");
              }
              return (ISearchCondition<String>)SubCriteria["FailureDescription"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="Data")]
        public ISearchCondition<XmlDocument> Data
        {
            get
            {
              if (!SubCriteria.ContainsKey("Data"))
              {
                 SubCriteria["Data"] = new SearchCondition<XmlDocument>("Data");
              }
              return (ISearchCondition<XmlDocument>)SubCriteria["Data"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="ExternalRequestQueueGUID")]
        public ISearchCondition<ServerEntityKey> ExternalRequestQueueKey
        {
            get
            {
              if (!SubCriteria.ContainsKey("ExternalRequestQueueKey"))
              {
                 SubCriteria["ExternalRequestQueueKey"] = new SearchCondition<ServerEntityKey>("ExternalRequestQueueKey");
              }
              return (ISearchCondition<ServerEntityKey>)SubCriteria["ExternalRequestQueueKey"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="ProcessorID")]
        public ISearchCondition<String> ProcessorID
        {
            get
            {
              if (!SubCriteria.ContainsKey("ProcessorID"))
              {
                 SubCriteria["ProcessorID"] = new SearchCondition<String>("ProcessorID");
              }
              return (ISearchCondition<String>)SubCriteria["ProcessorID"];
            } 
        }
        [EntityFieldDatabaseMappingAttribute(TableName="WorkQueue", ColumnName="GroupID")]
        public ISearchCondition<String> GroupID
        {
            get
            {
              if (!SubCriteria.ContainsKey("GroupID"))
              {


Please complete the code given below. 
/*
 * Handlers.cs - Implementation of the "I18N.Common.Handlers" class.
 *
 * Copyright (c) 2002  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
namespace I18N.Common
{
using System;
using System.Collections.Generic;
// This class provides an internal list of handlers, for runtime
// engines that do not implement the altered "GetFile" semantics.
// The list must be kept up to date manually.
public sealed class Handlers
{
    public static readonly String[] List = {
        "I18N.CJK.CP932",
        "I18N.CJK.CP936",
        "I18N.CJK.CP949",
        "I18N.CJK.CP950",
        "I18N.CJK.CP50220",
        "I18N.CJK.CP50221",
        "I18N.CJK.CP50222",
        "I18N.CJK.CP51932",
        "I18N.CJK.CP51949",
        "I18N.CJK.CP54936",
        "I18N.CJK.ENCbig5",
        "I18N.CJK.ENCgb2312",
        "I18N.CJK.ENCshift_jis",
        "I18N.CJK.ENCiso_2022_jp",
        "I18N.CJK.ENCeuc_jp",
        "I18N.CJK.ENCeuc_kr",
        "I18N.CJK.ENCuhc",
        "I18N.CJK.ENCgb18030",
        "I18N.MidEast.CP1254",
        "I18N.MidEast.ENCwindows_1254",
        "I18N.MidEast.CP1255",
        "I18N.MidEast.ENCwindows_1255",
        "I18N.MidEast.CP1256",
        "I18N.MidEast.ENCwindows_1256",
        "I18N.MidEast.CP28596",
        "I18N.MidEast.ENCiso_8859_6",
        "I18N.MidEast.CP28598",
        "I18N.MidEast.ENCiso_8859_8",
        "I18N.MidEast.CP28599",
        "I18N.MidEast.ENCiso_8859_9",
        "I18N.MidEast.CP38598",
        "I18N.MidEast.ENCwindows_38598",
        "I18N.Other.CP1251",
        "I18N.Other.ENCwindows_1251",
        "I18N.Other.CP1257",
        "I18N.Other.ENCwindows_1257",
        "I18N.Other.CP1258",
        "I18N.Other.ENCwindows_1258",
        "I18N.Other.CP20866",
        "I18N.Other.ENCkoi8_r",
        "I18N.Other.CP21866",
        "I18N.Other.ENCkoi8_u",
        "I18N.Other.CP28594",
        "I18N.Other.ENCiso_8859_4",
        "I18N.Other.CP28595",
        "I18N.Other.ENCiso_8859_5",
        "I18N.Other.ISCIIEncoding",
        "I18N.Other.CP57002",
        "I18N.Other.CP57003",
        "I18N.Other.CP57004",
        "I18N.Other.CP57005",
        "I18N.Other.CP57006",
        "I18N.Other.CP57007",
        "I18N.Other.CP57008",
        "I18N.Other.CP57009",
        "I18N.Other.CP57010",
        "I18N.Other.CP57011",
        "I18N.Other.ENCx_iscii_de",
        "I18N.Other.ENCx_iscii_be",
        "I18N.Other.ENCx_iscii_ta",
        "I18N.Other.ENCx_iscii_te",
        "I18N.Other.ENCx_iscii_as",
        "I18N.Other.ENCx_iscii_or",
        "I18N.Other.ENCx_iscii_ka",
        "I18N.Other.ENCx_iscii_ma",
        "I18N.Other.ENCx_iscii_gu",
        "I18N.Other.ENCx_iscii_pa",
        "I18N.Other.CP874",
        "I18N.Other.ENCwindows_874",
        "I18N.Rare.CP1026",
        "I18N.Rare.ENCibm1026",
        "I18N.Rare.CP1047",
        "I18N.Rare.ENCibm1047",
        "I18N.Rare.CP1140",
        "I18N.Rare.ENCibm01140",
        "I18N.Rare.CP1141",
        "I18N.Rare.ENCibm01141",
        "I18N.Rare.CP1142",
        "I18N.Rare.ENCibm01142",
        "I18N.Rare.CP1143",
        "I18N.Rare.ENCibm01143",
        "I18N.Rare.CP1144",
        "I18N.Rare.ENCibm1144",
        "I18N.Rare.CP1145",
        "I18N.Rare.ENCibm1145",
        "I18N.Rare.CP1146",
        "I18N.Rare.ENCibm1146",
        "I18N.Rare.CP1147",
        "I18N.Rare.ENCibm1147",
        "I18N.Rare.CP1148",
        "I18N.Rare.ENCibm1148",
        "I18N.Rare.CP1149",
        "I18N.Rare.ENCibm1149",
        "I18N.Rare.CP20273",
        "I18N.Rare.ENCibm273",
        "I18N.Rare.CP20277",
        "I18N.Rare.ENCibm277",
        "I18N.Rare.CP20278",
        "I18N.Rare.ENCibm278",
        "I18N.Rare.CP20280",
        "I18N.Rare.ENCibm280",
        "I18N.Rare.CP20284",
        "I18N.Rare.ENCibm284",
        "I18N.Rare.CP20285",
        "I18N.Rare.ENCibm285",
        "I18N.Rare.CP20290",
        "I18N.Rare.ENCibm290",
        "I18N.Rare.CP20297",
        "I18N.Rare.ENCibm297",
        "I18N.Rare.CP20420",
        "I18N.Rare.ENCibm420",
        "I18N.Rare.CP20424",
        "I18N.Rare.ENCibm424",
        "I18N.Rare.CP20871",
        "I18N.Rare.ENCibm871",
        "I18N.Rare.CP21025",
        "I18N.Rare.ENCibm1025",
        "I18N.Rare.CP37",
        "I18N.Rare.ENCibm037",
        "I18N.Rare.CP500",
        "I18N.Rare.ENCibm500",
        "I18N.Rare.CP708",
        "I18N.Rare.ENCasmo_708",
        "I18N.Rare.CP852",
        "I18N.Rare.ENCibm852",
        "I18N.Rare.CP855",
        "I18N.Rare.ENCibm855",
        "I18N.Rare.CP857",
        "I18N.Rare.ENCibm857",
        "I18N.Rare.CP858",
        "I18N.Rare.ENCibm00858",
        "I18N.Rare.CP862",
        "I18N.Rare.ENCibm862",
        "I18N.Rare.CP864",
        "I18N.Rare.ENCibm864",
        "I18N.Rare.CP866",
        "I18N.Rare.ENCibm866",
        "I18N.Rare.CP869",
        "I18N.Rare.ENCibm869",
        "I18N.Rare.CP870",
        "I18N.Rare.ENCibm870",
        "I18N.Rare.CP875",
        "I18N.Rare.ENCibm875",
        "I18N.West.CP10000",
        "I18N.West.ENCmacintosh",
        "I18N.West.CP10079",
        "I18N.West.ENCx_mac_icelandic",
        "I18N.West.CP1250",
        "I18N.West.ENCwindows_1250",
        "I18N.West.CP1252",
        "I18N.West.ENCwindows_1252",
        "I18N.West.CP1253",
        "I18N.West.ENCwindows_1253",
        "I18N.West.CP28592",
        "I18N.West.ENCiso_8859_2",
        "I18N.West.CP28593",
        "I18N.West.ENCiso_8859_3",
        "I18N.West.CP28597",
        "I18N.West.ENCiso_8859_7",
        "I18N.West.CP28605",
        "I18N.West.ENCiso_8859_15",
        "I18N.West.CP437",
        "I18N.West.ENCibm437",
        "I18N.West.CP850",
        "I18N.West.ENCibm850",
        "I18N.West.CP860",
        "I18N.West.ENCibm860",
        "I18N.West.CP861",
        "I18N.West.ENCibm861",
        "I18N.West.CP863",
        "I18N.West.ENCibm863",
        "I18N.West.CP865",
        "I18N.West.ENCibm865"
    };
	
	static Dictionary<string, string> aliases;
	public static string GetAlias (string name)
	{
		if (aliases == null)
			BuildHash ();
		string v;
		aliases.TryGetValue (name, out v);
		return v;
	}
	static void BuildHash ()
	{
		aliases = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
		aliases.Add ("arabic", "iso_8859_6");
		aliases.Add ("csISOLatinArabic", "iso_8859_6");
		aliases.Add ("ECMA_114", "iso_8859_6");
		aliases.Add ("ISO_8859_6:1987", "iso_8859_6");
		aliases.Add ("iso_ir_127", "iso_8859_6");
		aliases.Add ("cp1256" ,"windows_1256");
		aliases.Add ("csISOLatin4", "iso_8859_4");
		aliases.Add ("ISO_8859_4:1988", "iso_8859_4");
		aliases.Add ("iso_ir_110", "iso_8859_4");
		aliases.Add ("l4", "iso_8859_4");
		aliases.Add ("latin4", "iso_8859_4");
		aliases.Add ("cp852" ,"ibm852");
		aliases.Add ("csISOLatin2", "iso_8859_2");
		aliases.Add ("iso_8859_2:1987", "iso_8859_2");
		aliases.Add ("iso8859_2", "iso_8859_2");
		aliases.Add ("iso_ir_101", "iso_8859_2");
		aliases.Add ("l2", "iso_8859_2");
		aliases.Add ("latin2", "iso_8859_2");
		aliases.Add ("x-cp1250", "windows_1250");
		aliases.Add ("chinese", "gb2312");
		aliases.Add ("CN-GB", "gb2312");
		aliases.Add ("csGB2312", "gb2312");
		aliases.Add ("csGB231280", "gb2312");
		aliases.Add ("csISO58GB231280", "gb2312");
		aliases.Add ("GB_2312_80", "gb2312");
		aliases.Add ("GB231280", "gb2312");
		aliases.Add ("GB2312_80", "gb2312");


Please complete the code given below. 
"""Tools for parsing a regular expression into a Pattern."""
import collections
import string
import charsource
import pattern as p
# Characters that represent themselves in a regular expression.
# TODO(jasonpr): Handle $ and ^ specially at edges of regex.
_CHAR_LITERALS = string.ascii_letters + string.digits + '!"#$%&\',-/:;<=>@^_`~]} \t\n\r'
# Characters that represent themselves inside a square-bracket expression.
_GROUP_CHARS = string.ascii_letters + string.digits + '!"#$%&\'()*+,-./:;<=>?@[^_`{|}~'
# Characters that represent themselves when escaped with a backslash.
_IDENTIY_ESCAPES = r'.[\()*+?{|'
# Characters that represent a character class when escaped with a backslash.
_CHARACTER_CLASSES = {
    'd': string.digits,
    'w': string.ascii_letters + string.digits + '_',
    'h': string.hexdigits,
    # TODO(jasonpr): Make an informed decision, rather than blindly
    # inheritting this definition from Python.
    's': string.whitespace,
    }
_BRACKET_CHARACTER_CLASSES = {
    'alnum': set(string.ascii_letters + string.digits),
    'alpha': set(string.ascii_letters),
    'digit': set(string.digits),
    'lower': set(string.ascii_lowercase),
    'print': set(string.printable),
    'punct': set(string.punctuation),
    # TODO(jasonpr): Make an informed decision, rather than blindly
    # inheritting this definition from Python.
    'space': set(string.whitespace),
    'upper': set(string.ascii_uppercase),
    'xdigit': set(string.hexdigits),
    }
def parse_regex(regex_string):
    """Convert a regular expression string into a Pattern."""
    return _parse_regex(charsource.GetPutSource(regex_string))
# The following _parse_* methods form a recursive descent parser
# that respect the order of operations in a regular expression.
def _parse_regex(source):
    """Parse any regex into a Pattern."""
    return _parse_alternation(source)
def _parse_alternation(source):
    """Parse an alternation expression, like 'ab|cd|ef'."""
    parts = []
    # Act as though the last character was a '|', so we get the
    # initial element of the alternation.
    last_char = '|'
    while last_char == '|':
        parts.append(_parse_concatenation(source))
        last_char = source.get()
    # Put back the non-alternation character.
    source.put(last_char)
    return p.Or(*parts)
def _parse_concatenation(source):
    """Parse a concatenation expression, like 'abc' or 'a(b|c)d*'."""
    parts = []
    duplication = _parse_duplication(source)
    # If we're expecting a concatenation, there MUST be at least
    # one (first) element!
    assert duplication
    while duplication:
        parts.append(duplication)
        duplication = _parse_duplication(source)
    return p.Sequence(*parts)
def _parse_duplication(source):
    """Parse a duplication expression, like 'a*' or '(a|b){3,5}'."""
    duplicated = _parse_parenthesization(source)
    if not duplicated:
        return None
    duplicator = source.get()
    if duplicator == '?':
        return p.Maybe(duplicated)
    elif duplicator == '*':
        return p.Star(duplicated)
    elif duplicator == '+':
        return p.Plus(duplicated)
    elif duplicator == '{':
        min_repeats = _parse_positive_int(source)
        range_continuation = source.get()
        # We will ultimately expect a closing curly brace, but
        # we might see a comma and a max repeats value, first.
        if range_continuation == ',':
            max_repeats = _parse_positive_int(source)
            range_continuation = source.get()
        else:
            max_repeats = min_repeats
        if range_continuation != '}':
            raise ValueError('Expected "}", but got "%s".' %
                             range_continuation)
        return p.Repeat(duplicated, min_repeats, max_repeats)
    else:
        source.put(duplicator)
        return duplicated
def _parse_parenthesization(source):
    """Parse a parenthesization pattern, like '(a|b)' or '[ab]' or 'a'.
    Note that '[ab]' is a parenthesization, since it is equivalent
    to '([ab])'.  Similarly, 'a' is equivalent to '(a)'.
    """
    first_char = source.get()
    if first_char == '(':
        enclosed_regex = _parse_regex(source)
        close_paren = source.get()
        assert close_paren == ')'
        return enclosed_regex
    # Otherwise, this must just be a group.  (Groups have just as
    # tight of binding as a parenthesization.)
    source.put(first_char)
    return _parse_group(source)
def _parse_group(source):
    """Parse a group pattern, like '[abc]' or 'a'.
    Note that 'a' is a group, since 'a' is equivalent to '[a]'.
    """
    first_char = source.get()
    if first_char == '[':
        second_char = source.get()
        if second_char == '^':
            negating = True
        else:
            source.put(second_char)
            negating = False
        group_chars = _parse_group_chars(source)
        result = p.Selection(group_chars, negating)
        close_brace = source.get()
        assert close_brace == ']'
        return result
    # Otherwise, it's a single normal character.
    source.put(first_char)
    return _parse_atom(source)
def _parse_group_chars(source):
    """Parse the characters from a group specification.
    This is just a string of characters allowable in a group specification.
    For example, a valid parse is 'aA1.?', since '[aA1.?]' is a valid group.
    """
    chars = set()
    while True:
        range_chars = _parse_group_range(source)
        if range_chars:
            for char in range_chars:
                chars.add(char)
            continue
        char_class = _parse_char_class(source)
        if char_class:
            chars |= char_class
            continue
        char = source.get()
        if not char:
            raise ValueError('Unexpected end of stream.')
        if char not in _GROUP_CHARS:
            source.put(char)
            break
        chars.add(char)
    return ''.join(chars)
def _parse_atom(source):
    """Parse a single regex atom.
    An atom is a period ('.'), a character literal, or an escape sequence.
    """
    char = source.get()
    if not char:
        # For good measure, put the EOF back on!
        # This doesn't really do anything, since the source will
        # generate EOFs forever.
        source.put(char)
        return None
    elif char == '.':
        return p.Anything()
    elif char in _CHAR_LITERALS:
        return p.String(char)
    elif char == '\\':
        escaped = source.get()
        if escaped in _IDENTIY_ESCAPES:
            return p.String(escaped)
        elif escaped in _CHARACTER_CLASSES:
            return p.Selection(_CHARACTER_CLASSES[escaped])
        else:
            raise ValueError('Unexpected escape sequence, \\%s.', escaped)
    else:
        source.put(char)
        return None
def _parse_positive_int(source):
    """Parse a positive integer.
    That is, parse a sequence of one or more digits.
    """
    digits = []
    next_char = source.get()
    assert next_char and next_char in string.digits
    while next_char and next_char in string.digits:
        digits.append(next_char)
        next_char = source.get()
    source.put(next_char)
    return int(''.join(digits))
def _parse_group_range(source):
    """Parse a three-character group range expression.
    Return the set of characters represented by the range.
    For example, parsing the expression 'c-e' from the source returns
    set(['c', 'd', 'e']).
    """
    start = source.get()
    if start not in _GROUP_CHARS:
        source.put(start)
        return None
    middle = source.get()
    if middle != '-':
        source.put(middle)
        source.put(start)
        return None
    end = source.get()
    if end not in _GROUP_CHARS:
        source.put(end)
        source.put(middle)
        source.put(start)
        return None
    range_chars = set()
    for ascii_value in range(ord(start), ord(end) + 1):
        range_chars.add(chr(ascii_value))
    return range_chars
def _parse_char_class(source):
    for class_name, class_contents in _BRACKET_CHARACTER_CLASSES.iteritems():


Please complete the code given below. 
# -*- coding: utf-8 -*-
"""
Created on Tue Nov  8 14:27:22 2016
@author: Viktor
"""
import numpy as np
from sklearn.datasets import fetch_mldata
from matplotlib import pyplot as plt
from skimage.io import imread
from skimage.io import imshow
from skimage.morphology import opening, closing
from scipy import ndimage
from sklearn.neighbors import KNeighborsClassifier
#ucitavanje MNIST dataseta
mnist = fetch_mldata('MNIST original')
print(mnist.data.shape)
print(mnist.target.shape)
print(np.unique(mnist.target))
img = 255-mnist.data[12345]
img = img.reshape(28,28)
plt.imshow(-img, cmap='Greys')
#iscitavanje dataseta i smestanje u matricu radi lakseg pristupa
numbers = [0]*10
numbers[0] = mnist['data'][np.where(mnist['target'] == 0.)[0]]
numbers[1] = mnist['data'][np.where(mnist['target'] == 1.)[0]]
numbers[2] = mnist['data'][np.where(mnist['target'] == 2.)[0]]
numbers[3] = mnist['data'][np.where(mnist['target'] == 3.)[0]]
numbers[4] = mnist['data'][np.where(mnist['target'] == 4.)[0]]
numbers[5] = mnist['data'][np.where(mnist['target'] == 5.)[0]]
numbers[6] = mnist['data'][np.where(mnist['target'] == 6.)[0]]
numbers[7] = mnist['data'][np.where(mnist['target'] == 7.)[0]]
numbers[8] = mnist['data'][np.where(mnist['target'] == 8.)[0]]
numbers[9] = mnist['data'][np.where(mnist['target'] == 9.)[0]]
test = numbers[0][123]
res = numbers[0][123] == numbers[0][124]
percent_hit = np.count_nonzero(res) / 784.0
representative_number = [0]*10
for j in range(0,10):
    representative_number[j] = np.zeros(np.shape(numbers[j][0]), dtype='float')
    for i in range(0,len(numbers[j])):
        representative_number[j] = representative_number[j] + numbers[j][i]
    representative_number[j] = (representative_number[j])/len(numbers[j])
def processing(path):
    img = imread(path)
    gray = rgb2gray(img)
    binary = 1 - (gray > 0.5)
    binary = closing(binary)
    binary = opening(binary)
    labeled, nr_objects = ndimage.label(binary)
    return nr_objects
def poklapanje(niz1, niz2):
    mera_poklapanja = 0.0
    for i in range(0,len(niz1)):
        if(niz1[i]==niz2[i]):
            mera_poklapanja = mera_poklapanja + 1
            
    return mera_poklapanja/len(niz1)
    
def ucitavanje(path):
    image_path = []
    with open(path) as f:
        data = f.read()
        lines = data.split('\n')
        for i, line in enumerate(lines):
            if(i>1):
                cols = line.split('\t')
                if(cols[0]!=''):
                    image_path.append(cols[0])
                
        f.close()
        
    return image_path
def upis(path,image_path,result):
    with open(path,'w') as f:
        f.write('RA 1/2013 Viktor Sanca\n')
        f.write('file\tsum\n')
        for i in range(0,len(image_path)):
            f.write(image_path[i]+'\t'+str(result[i])+'\n')
        
        f.close()
    
def get_img(image_path):
    img = imread(image_path)
    gray = rgb2gray(img)
    #gray = closing(gray)
    #gray = opening(gray)
    #binary = (gray < 0.5)
    return gray
def binarize(img):
    return img>1
    
def rgb2gray(img_rgb):
    img_gray = np.ndarray((img_rgb.shape[0], img_rgb.shape[1]))
    img_gray = 0.8*img_rgb[:, :, 0] + 0.2*img_rgb[:, :, 1] + 1*img_rgb[:, :, 2]
    img_gray = img_gray.astype('uint8')
    return img_gray
def mark_indices(image):
    starting_indices = []
    img = image.reshape(640*480)
    for i in range(0,(640)*(480-28)):
        if(img[i]<10 and img[i+27]<10 and img[i+27*(640)]<10 and img[i+27*(640)+27]<10):
            starting_indices.append(i)
            
    return starting_indices
def get_image_from_indice(image,start_indice):
    image28_28 = np.empty((28*28),dtype='uint8')
    img = image.reshape(640*480)
    
    for i in range(0,28):
        for j in range(0,28):
            image28_28[28*i+j]=img[start_indice+i*(640)+j]
    return image28_28
    
def find_number(image28_28):
    mmx = [0]*10
    for i in range(0,10):
        for j in range(0,len(numbers[i])):
            res = binarize(image28_28) == binarize(numbers[i][j])
            if(np.count_nonzero(res)>mmx[i]):
                mmx[i]=np.count_nonzero(res)
    
    return max_idx(mmx)
    
def max_idx(lista):
    mx = max(lista)
    for i in range(0,len(lista)):
        if(lista[i]==mx):
            return i
            
    return -1
    
image_path = []
result = []
    
in_path = 'level-1-mnist-train/level-1-mnist/out.txt'
out_path = 'level-1-mnist-test/level-1-mnist-test/out.txt'
train_path = 'level-1-mnist-train/level-1-mnist/'
test_path = 'level-1-mnist-test/level-1-mnist-test/'
image_paths = ucitavanje(out_path)
#knn = KNeighborsClassifier()
knn = KNeighborsClassifier(n_neighbors=2000,weights='distance',algorithm='auto',n_jobs=-1)
knn.fit(mnist.data,mnist.target)
suma = [0]*len(image_paths)
for i in range(0,len(image_paths)):
    print('Image'+str(i+1)+'/'+str(len(image_paths)))
    img = get_img(test_path+image_paths[i])
    start_indices = mark_indices(img.reshape(640*480))
    
    for start_indice in start_indices:
        img_d = get_image_from_indice(img,start_indice)
        #nr = find_number(img_d)
        nr = knn.predict(img_d)
        suma[i] = suma[i] + nr[0]
        suma[i] = int(suma[i])
for i in range(0,len(suma)):
    suma[i] = float(suma[i])
        
upis(out_path, image_paths, suma)
image28_28 = img_d
mmx = [0]*10
for i in range(0,10):
    for j in range(0,len(numbers[i])):
        res = image28_28 == numbers[i][j]
        if(np.count_nonzero(res)>mmx[i]):
            mmx[i]=np.count_nonzero(res)
    
total = np.zeros(784, dtype='float')
for i in range(0,10):
    total = total + representative_number[i]
        
img = representative_number[4]
img = img.reshape(28,28)
plt.imshow(img, cmap='Greys')


Please complete the code given below. 
/*
 * *************************************************************************************
 *  Copyright (C) 2008 EsperTech, Inc. All rights reserved.                            *
 *  http://esper.codehaus.org                                                          *
 *  http://www.espertech.com                                                           *
 *  ---------------------------------------------------------------------------------- *
 *  The software in this package is published under the terms of the GPL license       *
 *  a copy of which has been included with this distribution in the license.txt file.  *
 * *************************************************************************************
 */
package com.espertech.esper.regression.epl;
import com.espertech.esper.client.*;
import com.espertech.esper.client.soda.*;
import com.espertech.esper.support.bean.*;
import com.espertech.esper.support.client.SupportConfigFactory;
import com.espertech.esper.support.util.SupportUpdateListener;
import com.espertech.esper.util.SerializableObjectCopier;
import junit.framework.TestCase;
public class TestSubselectIn extends TestCase
{
    private EPServiceProvider epService;
    private SupportUpdateListener listener;
    public void setUp()
    {
        Configuration config = SupportConfigFactory.getConfiguration();
        config.addEventType("S0", SupportBean_S0.class);
        config.addEventType("S1", SupportBean_S1.class);
        config.addEventType("S2", SupportBean_S2.class);
        epService = EPServiceProviderManager.getDefaultProvider(config);
        epService.initialize();
        listener = new SupportUpdateListener();
    }
    public void testInSelect()
    {
        String stmtText = "select id in (select id from S1.win:length(1000)) as value from S0";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        runTestInSelect();
    }
    public void testInSelectOM() throws Exception
    {
        EPStatementObjectModel subquery = new EPStatementObjectModel();
        subquery.setSelectClause(SelectClause.create("id"));
        subquery.setFromClause(FromClause.create(FilterStream.create("S1").addView(View.create("win", "length", Expressions.constant(1000)))));
        EPStatementObjectModel model = new EPStatementObjectModel();
        model.setFromClause(FromClause.create(FilterStream.create("S0")));
        model.setSelectClause(SelectClause.create().add(Expressions.subqueryIn("id", subquery), "value"));
        model = (EPStatementObjectModel) SerializableObjectCopier.copy(model);
        String stmtText = "select id in (select id from S1.win:length(1000)) as value from S0";
        assertEquals(stmtText, model.toEPL());
        EPStatement stmt = epService.getEPAdministrator().create(model);
        stmt.addListener(listener);
        runTestInSelect();
    }
    public void testInSelectCompile() throws Exception
    {
        String stmtText = "select id in (select id from S1.win:length(1000)) as value from S0";
        EPStatementObjectModel model = epService.getEPAdministrator().compileEPL(stmtText);
        model = (EPStatementObjectModel) SerializableObjectCopier.copy(model);
        assertEquals(stmtText, model.toEPL());
        EPStatement stmt = epService.getEPAdministrator().create(model);
        stmt.addListener(listener);
        runTestInSelect();
    }
    private void runTestInSelect()
    {
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(-1));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(-1));
        assertEquals(true, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(5));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(4));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(5));
        assertEquals(true, listener.assertOneGetNewAndReset().get("value"));
    }
    public void testInSelectWhere()
    {
        String stmtText = "select id in (select id from S1.win:length(1000) where id > 0) as value from S0";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(-1));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(-1));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(5));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(4));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(5));
        assertEquals(true, listener.assertOneGetNewAndReset().get("value"));
    }
    public void testInSelectWhereExpressions()
    {
        String stmtText = "select 3*id in (select 2*id from S1.win:length(1000)) as value from S0";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(-1));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(-1));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(6));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(4));
        assertEquals(true, listener.assertOneGetNewAndReset().get("value"));
    }
    public void testInWildcard()
    {
        epService.getEPAdministrator().getConfiguration().addEventType("ArrayBean", SupportBeanArrayCollMap.class);
        String stmtText = "select s0.anyObject in (select * from S1.win:length(1000)) as value from ArrayBean s0";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        SupportBean_S1 s1 = new SupportBean_S1(100);
        SupportBeanArrayCollMap arrayBean = new SupportBeanArrayCollMap(s1);
        epService.getEPRuntime().sendEvent(s1);
        epService.getEPRuntime().sendEvent(arrayBean);
        assertEquals(true, listener.assertOneGetNewAndReset().get("value"));
        SupportBean_S2 s2 = new SupportBean_S2(100);
        arrayBean.setAnyObject(s2);
        epService.getEPRuntime().sendEvent(s2);
        epService.getEPRuntime().sendEvent(arrayBean);
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
    }
    public void testInNullable()
    {
        String stmtText = "select id from S0 as s0 where p00 in (select p10 from S1.win:length(1000))";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "a"));
        assertFalse(listener.isInvoked());
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2, null));
        assertFalse(listener.isInvoked());
        epService.getEPRuntime().sendEvent(new SupportBean_S1(-1, "A"));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(3, null));
        assertFalse(listener.isInvoked());
        epService.getEPRuntime().sendEvent(new SupportBean_S0(4, "A"));
        assertEquals(4, listener.assertOneGetNewAndReset().get("id"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(-2, null));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(5, null));
        assertFalse(listener.isInvoked());
    }
    public void testInNullableCoercion()
    {
        String stmtText = "select longBoxed from " + SupportBean.class.getName() + "(string='A') as s0 " +
                          "where longBoxed in " +
                          "(select intBoxed from " + SupportBean.class.getName() + "(string='B').win:length(1000))";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        sendBean("A", 0, 0L);
        sendBean("A", null, null);
        assertFalse(listener.isInvoked());
        sendBean("B", null, null);
        sendBean("A", 0, 0L);
        assertFalse(listener.isInvoked());
        sendBean("A", null, null);
        assertFalse(listener.isInvoked());
        sendBean("B", 99, null);
        sendBean("A", null, null);
        assertFalse(listener.isInvoked());
        sendBean("A", null, 99l);
        assertEquals(99L, listener.assertOneGetNewAndReset().get("longBoxed"));
        sendBean("B", 98, null);
        sendBean("A", null, 98l);
        assertEquals(98L, listener.assertOneGetNewAndReset().get("longBoxed"));
    }
    public void testInNullRow()
    {
        String stmtText = "select intBoxed from " + SupportBean.class.getName() + "(string='A') as s0 " +
                          "where intBoxed in " +
                          "(select longBoxed from " + SupportBean.class.getName() + "(string='B').win:length(1000))";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        sendBean("B", 1, 1l);
        sendBean("A", null, null);
        assertFalse(listener.isInvoked());
        sendBean("A", 1, 1l);
        assertEquals(1, listener.assertOneGetNewAndReset().get("intBoxed"));
        sendBean("B", null, null);
        sendBean("A", null, null);
        assertFalse(listener.isInvoked());
        sendBean("A", 1, 1l);
        assertEquals(1, listener.assertOneGetNewAndReset().get("intBoxed"));
    }
    public void testNotInNullRow()
    {
        String stmtText = "select intBoxed from " + SupportBean.class.getName() + "(string='A') as s0 " +
                          "where intBoxed not in " +
                          "(select longBoxed from " + SupportBean.class.getName() + "(string='B').win:length(1000))";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        sendBean("B", 1, 1l);
        sendBean("A", null, null);
        assertFalse(listener.isInvoked());
        sendBean("A", 1, 1l);
        assertFalse(listener.isInvoked());
        sendBean("B", null, null);
        sendBean("A", null, null);
        assertFalse(listener.isInvoked());
        sendBean("A", 1, 1l);
        assertFalse(listener.isInvoked());
    }
    public void testNotInSelect()
    {
        String stmtText = "select not id in (select id from S1.win:length(1000)) as value from S0";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
        assertEquals(true, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(-1));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
        assertEquals(true, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(-1));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S1(5));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(4));
        assertEquals(true, listener.assertOneGetNewAndReset().get("value"));
        epService.getEPRuntime().sendEvent(new SupportBean_S0(5));
        assertEquals(false, listener.assertOneGetNewAndReset().get("value"));
    }
    public void testNotInNullableCoercion()
    {
        String stmtText = "select longBoxed from " + SupportBean.class.getName() + "(string='A') as s0 " +
                          "where longBoxed not in " +
                          "(select intBoxed from " + SupportBean.class.getName() + "(string='B').win:length(1000))";
        EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
        stmt.addListener(listener);
        sendBean("A", 0, 0L);
        assertEquals(0L, listener.assertOneGetNewAndReset().get("longBoxed"));
        sendBean("A", null, null);
        assertEquals(null, listener.assertOneGetNewAndReset().get("longBoxed"));
        sendBean("B", null, null);
        sendBean("A", 1, 1L);
        assertFalse(listener.isInvoked());


Please complete the code given below. 
package net.brokentrain.ftf.ui.gui.dialog;
import net.brokentrain.ftf.ui.gui.GUI;
import net.brokentrain.ftf.ui.gui.properties.BrowserTabProperties;
import net.brokentrain.ftf.ui.gui.properties.ConnectionProperties;
import net.brokentrain.ftf.ui.gui.properties.PropertyPage;
import net.brokentrain.ftf.ui.gui.properties.QueryTabProperties;
import net.brokentrain.ftf.ui.gui.properties.SystemTrayProperties;
import net.brokentrain.ftf.ui.gui.properties.TransferTabProperties;
import net.brokentrain.ftf.ui.gui.properties.ViewProperties;
import net.brokentrain.ftf.ui.gui.properties.services.ArXivProperties;
import net.brokentrain.ftf.ui.gui.properties.services.DOIProperties;
import net.brokentrain.ftf.ui.gui.properties.services.GoogleDesktopSearchProperties;
import net.brokentrain.ftf.ui.gui.properties.services.GoogleScholarProperties;
import net.brokentrain.ftf.ui.gui.properties.services.GoogleWebSearchProperties;
import net.brokentrain.ftf.ui.gui.properties.services.PlosJournalsProperties;
import net.brokentrain.ftf.ui.gui.properties.services.PubMedCentralProperties;
import net.brokentrain.ftf.ui.gui.properties.services.PubMedProperties;
import net.brokentrain.ftf.ui.gui.properties.services.ScirusProperties;
import net.brokentrain.ftf.ui.gui.properties.services.ServicesProperties;
import net.brokentrain.ftf.ui.gui.properties.services.TerrierProperties;
import net.brokentrain.ftf.ui.gui.properties.services.WebOfKnowledgeProperties;
import net.brokentrain.ftf.ui.gui.properties.services.YahooWebSearchProperties;
import net.brokentrain.ftf.ui.gui.settings.SettingsRegistry;
import net.brokentrain.ftf.ui.gui.settings.SettingsSaver;
import net.brokentrain.ftf.ui.gui.util.FontUtil;
import net.brokentrain.ftf.ui.gui.util.LayoutDataUtil;
import net.brokentrain.ftf.ui.gui.util.LayoutUtil;
import net.brokentrain.ftf.ui.gui.util.PaintUtil;
import net.brokentrain.ftf.ui.gui.util.StringUtil;
import net.brokentrain.ftf.ui.gui.util.WidgetUtil;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
/* 
 * TODO: This entire class could REALLY do with a re-think - since there were
 * few preference pages to think about they were just hard  coded, then it
 * started to grow and grow leading to this mess.  This should probably be made
 * dynamic and just build the *service* preference pages by seeing what is in
 * SettingsRegistry.services rather than hard coding them explicitly :(! This
 * kind of applies to the entire services package that is a sub-package of the
 * properties package, too.
 * NOTE: This is heavily based on RSSOwls code!
 * */
public class PreferencesDialog extends Dialog {
    public static int lastOpenedPropertyPage = 0;
    private static final int dialogMinWidth = 460;
    private GUI fetcherGui;
    private Composite buttonHolder;
    private Composite contentHolder;
    private Composite prefTitleHolder;
    private Label labelImgHolder;
    private Label labelPrefTitle;
    private PropertyPage activePropertyPage;
    private String lastSelectedItemText;
    private String title;
    private TreeItem arxiv;
    private TreeItem browserTab;
    private TreeItem connection;
    private TreeItem crawler;
    private TreeItem doi;
    private TreeItem google;
    private TreeItem googleDesktop;
    private TreeItem googleScholar;
    private TreeItem plosjournals;
    private TreeItem pubmed;
    private TreeItem pubmedCentral;
    private TreeItem queryTab;
    private TreeItem scirus;
    private TreeItem services;
    private TreeItem systemTray;
    private TreeItem terrier;
    private TreeItem transferTab;
    private TreeItem view;
    private TreeItem webofknowledge;
    private TreeItem yahoo;
    private Tree tree;
    public PreferencesDialog(Shell parentShell, String dialogTitle,
            GUI fetcherGui) {
        super(parentShell);
        this.title = dialogTitle;
        this.fetcherGui = fetcherGui;
        /* Init the PropertyChangeManager */
        PropertyPage.initPropertyChangeManager(fetcherGui);
    }
    // private void createGeneralProps() {
    // renewPropertyPage("General");
    // activePropertyPage = new GeneralProperties(contentHolder, fetcherGui);
    // }
    // private void createCrawlerProps() {
    // renewPropertyPage("Crawler");
    // activePropertyPage = new CrawlerProperties(contentHolder, fetcherGui);
    // }
    // private void createBrowserProps() {
    // renewPropertyPage("Browser");
    // }
    @Override
    protected void buttonPressed(int buttonId) {
        if (buttonId == IDialogConstants.OK_ID) {
            saveSettings();
        }
        if (activePropertyPage != null) {
            activePropertyPage.dispose();
        }
        super.buttonPressed(buttonId);
    }
    @Override
    protected void configureShell(Shell shell) {
        shell.setLayout(LayoutUtil.createGridLayout(1, 0, 5));
        shell.setText(title);
        shell.setSize(0, 0);
    }
    private void createArxivProperties() {
        renewPropertyPage("ArXiv");
        activePropertyPage = new ArXivProperties(contentHolder);
    }
    private void createBrowserTabProps() {
        renewPropertyPage("Internal Browser");
        activePropertyPage = new BrowserTabProperties(contentHolder);
    }
    // private void createLogTabProps() {
    // renewPropertyPage("Debug Log");
    // activePropertyPage = new LogTabProperties(contentHolder);
    // }
    @Override
    protected Control createButtonBar(Composite parent) {
        buttonHolder = new Composite(parent, SWT.NONE);
        buttonHolder.setLayout(LayoutUtil
                .createGridLayout(2, 0, 0, 5, 5, false));
        buttonHolder.setLayoutData(LayoutDataUtil.createGridData(
                GridData.FILL_HORIZONTAL, 2));
        Composite okCancelHolder = new Composite(buttonHolder, SWT.NONE);
        okCancelHolder.setLayout(LayoutUtil.createGridLayout(2, 0, 5, 5));
        okCancelHolder.setLayoutData(new GridData(SWT.END, SWT.TOP, false,
                false));
        if (GUI.display.getDismissalAlignment() == SWT.RIGHT) {
            createButton(okCancelHolder, IDialogConstants.CANCEL_ID, "Cancel",
                    false).setFont(FontUtil.dialogFont);
            createButton(okCancelHolder, IDialogConstants.OK_ID, "OK", true)
                    .setFont(FontUtil.dialogFont);
        } else {
            createButton(okCancelHolder, IDialogConstants.OK_ID, "OK", true)
                    .setFont(FontUtil.dialogFont);
            createButton(okCancelHolder, IDialogConstants.CANCEL_ID, "Cancel",
                    false).setFont(FontUtil.dialogFont);
        }
        return buttonHolder;
    }
    // private void createStatusTabProps() {
    // renewPropertyPage("Status");
    // activePropertyPage = new StatusTabProperties(contentHolder, fetcherGui);
    // }
    private void createConnectionProps() {
        renewPropertyPage("Connection");
        activePropertyPage = new ConnectionProperties(contentHolder, fetcherGui);
    }
    @Override
    protected Control createDialogArea(Composite parent) {
        Composite baseComposite = (Composite) super.createDialogArea(parent);
        baseComposite.setLayout(LayoutUtil.createGridLayout(2, 0, 5, 15, 0,
                false));
        baseComposite.setLayoutData(LayoutDataUtil.createGridData(
                GridData.FILL_BOTH, 1));
        Composite treeHolder = new Composite(baseComposite, SWT.NONE);
        treeHolder.setLayoutData(LayoutDataUtil.createGridData(
                GridData.FILL_VERTICAL, 1, convertHorizontalDLUsToPixels(140)));
        treeHolder.setLayout(LayoutUtil.createGridLayout(1, 5, 0));
        tree = new Tree(treeHolder, SWT.BORDER);
        tree.setFont(FontUtil.dialogFont);
        tree.setFocus();
        tree.setLayoutData(new GridData(GridData.FILL_BOTH));
        tree.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                handleTreeItemSelect();
            }
        });
        tree.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                TreeItem selectedItem = tree.getSelection()[0];
                if ((e.keyCode == SWT.CR) && (selectedItem.getItemCount() > 0)) {
                    selectedItem.setExpanded(!selectedItem.getExpanded());
                }
            }
        });
        tree.addListener(SWT.MouseDoubleClick, new Listener() {
            public void handleEvent(Event event) {
                if (tree.getSelectionCount() > 0) {
                    Rectangle clickedRect = event.getBounds();
                    Rectangle selectedRect = tree.getSelection()[0].getBounds();
                    /* Only handle event, if Mouse is over treeitem */
                    if (selectedRect.contains(clickedRect.x, clickedRect.y)) {
                        tree.getSelection()[0]
                                .setExpanded(!tree.getSelection()[0]
                                        .getExpanded());
                    }
                }
            }
        });
        populateTree();
        contentHolder = new Composite(baseComposite, SWT.NONE);
        contentHolder.setLayoutData(new GridData(GridData.FILL_BOTH
                | GridData.VERTICAL_ALIGN_BEGINNING));
        contentHolder.setLayout(LayoutUtil.createGridLayout(1, 5, 0));
        prefTitleHolder = new Composite(contentHolder, SWT.NONE);
        GridLayout prefTitleHolderLayout = new GridLayout(2, false);
        prefTitleHolderLayout.marginWidth = 1;
        prefTitleHolderLayout.marginHeight = 2;
        prefTitleHolderLayout.marginLeft = 4;
        prefTitleHolder.setLayout(prefTitleHolderLayout);
        prefTitleHolder.setLayoutData(LayoutDataUtil.createGridData(
                GridData.FILL_HORIZONTAL, 2));
        prefTitleHolder.setBackground(GUI.display
                .getSystemColor(SWT.COLOR_WHITE));
        prefTitleHolder.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent e) {
                e.gc.setForeground(GUI.display
                        .getSystemColor(SWT.COLOR_DARK_GRAY));
                Rectangle bounds = prefTitleHolder.getClientArea();
                bounds.height -= 2;
                bounds.width -= 1;
                e.gc.drawRectangle(bounds);
            }
        });
        setTreeSelection(lastOpenedPropertyPage);
        handleTreeItemSelect();
        Label seperator = new Label(baseComposite, SWT.HORIZONTAL
                | SWT.SEPARATOR);
        seperator.setLayoutData(LayoutDataUtil.createGridData(
                GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL,
                2));
        if (WidgetUtil.isset(tree.getHorizontalBar())) {
            tree.getHorizontalBar().setSelection(0);
        }
        return contentHolder;
    }
    private void createDOIProperties() {
        renewPropertyPage("DOI");
        activePropertyPage = new DOIProperties(contentHolder);
    }
    private void createGoogleDesktopSearchProperties() {
        renewPropertyPage("Google Desktop Search");
        activePropertyPage = new GoogleDesktopSearchProperties(contentHolder);
    }
    // private void createCiteSeerProperties() {
    // renewPropertyPage("Cite Seer");
    // activePropertyPage = new CiteSeerProperties(contentHolder);
    // }
    private void createGoogleScholarProperties() {
        renewPropertyPage("Google Scholar");
        activePropertyPage = new GoogleScholarProperties(contentHolder);
    }
    private void createGoogleWebSearchProperties() {
        renewPropertyPage("Google Web Search");
        activePropertyPage = new GoogleWebSearchProperties(contentHolder);
    }
    private void createPlosJournalsProperties() {
        renewPropertyPage("Plos Journals");
        activePropertyPage = new PlosJournalsProperties(contentHolder);
    }
    private void createPubMedCentralProperties() {
        renewPropertyPage("PubMed Central");
        activePropertyPage = new PubMedCentralProperties(contentHolder);
    }
    private void createPubMedProperties() {
        renewPropertyPage("PubMed");
        activePropertyPage = new PubMedProperties(contentHolder);
    }
    private void createQueryTabProps() {
        renewPropertyPage("Queries");
        activePropertyPage = new QueryTabProperties(contentHolder);
    }
    private void createScirusProperties() {
        renewPropertyPage("Scirus");
        activePropertyPage = new ScirusProperties(contentHolder);
    }
    private void createServicesProperties() {
        renewPropertyPage("Default Services");
        activePropertyPage = new ServicesProperties(contentHolder);
    }
    private void createSystemTrayProps() {
        renewPropertyPage("System Tray");
        activePropertyPage = new SystemTrayProperties(contentHolder, fetcherGui);
    }
    private void createTerrierProperties() {
        renewPropertyPage("Terrier");
        activePropertyPage = new TerrierProperties(contentHolder);
    }
    private void createTransferTabProps() {
        renewPropertyPage("Transfer");
        activePropertyPage = new TransferTabProperties(contentHolder);
    }
    private void createViewProps() {
        renewPropertyPage("View");
        activePropertyPage = new ViewProperties(contentHolder, fetcherGui);
    }
    private void createWebOfKnowledgeProperties() {
        renewPropertyPage("WebOfKnowledge");
        activePropertyPage = new WebOfKnowledgeProperties(contentHolder);
    }
    private void createYahooProperties() {
        renewPropertyPage("Yahoo Web Search");
        activePropertyPage = new YahooWebSearchProperties(contentHolder);
    }
    @Override
    protected int getShellStyle() {
        int style = SWT.TITLE | SWT.BORDER | SWT.RESIZE | SWT.APPLICATION_MODAL
                | getDefaultOrientation();
        return style;
    }
    void handleTreeItemSelect() {
        if (tree.getSelection().length == 0) {
            return;
        }
        if (tree.getSelection()[0].getText().equals(lastSelectedItemText)) {
            return;
        }
        lastSelectedItemText = tree.getSelection()[0].getText();
        // if (tree.getSelection()[0].getText().equals("General")) {
        // createGeneralProps();
        // lastOpenedPropertyPage = 0;
        // }
        // if (tree.getSelection()[0].getText().equals("Crawler")) {
        // createCrawlerProps();
        // lastOpenedPropertyPage = 23;
        // }
        /* Browser */
        // if (tree.getSelection()[0].getText().equals("Browser")) {
        // createBrowserProps();
        // lastOpenedPropertyPage = 1;
        // }
        /* Connection */
        if (tree.getSelection()[0].getText().equals("Connection")) {
            createConnectionProps();
            lastOpenedPropertyPage = 2;
        }
        /* System Tray */
        else if (tree.getSelection()[0].getText().equals("System Tray")) {
            createSystemTrayProps();
            lastOpenedPropertyPage = 3;
        }
        /* View */
        else if (tree.getSelection()[0].getText().equals("View")) {
            createViewProps();
            lastOpenedPropertyPage = 4;
        }
        /* Browser Tab */
        else if (tree.getSelection()[0].getText().equals("Internal Browser")) {
            createBrowserTabProps();
            lastOpenedPropertyPage = 5;
        }
        /* Log Tab */
        // else if (tree.getSelection()[0].getText().equals("Debug Log")) {
        // createLogTabProps();
        // lastOpenedPropertyPage = 6;
        // }
        /* Query Tab */
        else if (tree.getSelection()[0].getText().equals("Queries")) {
            createQueryTabProps();
            lastOpenedPropertyPage = 7;
        }
        /* Status Tab */
        // else if (tree.getSelection()[0].getText().equals("Status")) {
        // createStatusTabProps();
        // lastOpenedPropertyPage = 8;
        // }
        /* Transfer Tab */
        else if (tree.getSelection()[0].getText().equals("Transfer")) {
            createTransferTabProps();
            lastOpenedPropertyPage = 9;
        }
        /* Services */
        else if (tree.getSelection()[0].getText().equals("Services")) {
            createServicesProperties();
            lastOpenedPropertyPage = 10;
        }
        /* ArXiv */
        else if (tree.getSelection()[0].getText().equals("ArXiv")) {
            createArxivProperties();
            lastOpenedPropertyPage = 11;
        }
        /* CiteSeer */
        // else if (tree.getSelection()[0].getText().equals("Cite Seer")) {
        // createCiteSeerProperties();
        // lastOpenedPropertyPage = 12;
        // }
        /* DOI */
        else if (tree.getSelection()[0].getText().equals("DOI")) {
            createDOIProperties();
            lastOpenedPropertyPage = 13;
        }
        /* GoogleDesktopSearch */
        else if (tree.getSelection()[0].getText().equals(
                "Google Desktop Search")) {
            createGoogleDesktopSearchProperties();
            lastOpenedPropertyPage = 24;
        }
        /* Google */
        else if (tree.getSelection()[0].getText().equals("Google Web Search")) {
            createGoogleWebSearchProperties();
            lastOpenedPropertyPage = 14;
        }
        /* GoogleScholar */
        else if (tree.getSelection()[0].getText().equals("Google Scholar")) {
            createGoogleScholarProperties();
            lastOpenedPropertyPage = 15;
        }
        /* PlosJournals */
        else if (tree.getSelection()[0].getText().equals("Plos Journals")) {
            createPlosJournalsProperties();
            lastOpenedPropertyPage = 16;
        }
        /* PubMed */
        else if (tree.getSelection()[0].getText().equals("PubMed")) {
            createPubMedProperties();
            lastOpenedPropertyPage = 17;
        }
        /* PubMedCentral */
        else if (tree.getSelection()[0].getText().equals("PubMed Central")) {
            createPubMedCentralProperties();
            lastOpenedPropertyPage = 18;
        }
        /* Scirus */
        else if (tree.getSelection()[0].getText().equals("Scirus")) {
            createScirusProperties();
            lastOpenedPropertyPage = 19;
        }
        /* Terrier */
        else if (tree.getSelection()[0].getText().equals("Terrier")) {
            createTerrierProperties();
            lastOpenedPropertyPage = 20;
        }
        /* WebOfKnowledge */
        else if (tree.getSelection()[0].getText().equals("Web Of Knowledge")) {
            createWebOfKnowledgeProperties();
            lastOpenedPropertyPage = 21;
        }
        /* Yahoo */
        else if (tree.getSelection()[0].getText().equals("Yahoo Web Search")) {
            createYahooProperties();
            lastOpenedPropertyPage = 22;
        }
        contentHolder.layout();
        initializeBounds(false);
    }
    @Override
    protected void initializeBounds() {
        initializeBounds(true);
    }
    protected void initializeBounds(boolean updateLocation) {
        Point currentSize = getShell().getSize();
        Point bestSize = getShell().computeSize(
                convertHorizontalDLUsToPixels(dialogMinWidth), SWT.DEFAULT);
        Point location = (updateLocation == true) ? getInitialLocation(bestSize)
                : getShell().getLocation();
        if (updateLocation && (bestSize.y > currentSize.y)) {
            getShell()
                    .setBounds(location.x, location.y, bestSize.x, bestSize.y);
        } else if (bestSize.y > currentSize.y) {
            getShell().setSize(bestSize.x, bestSize.y);
        }
        getShell().setMinimumSize(bestSize.x, bestSize.y);
    }
    void populateTree() {
        String selectionText = null;
        if (tree.getSelectionCount() > 0) {
            selectionText = tree.getSelection()[0].getText();
        }
        if (tree.getItemCount() > 0) {
            tree.removeAll();
        }
        /* General properties */
        // general = new TreeItem(tree, SWT.NONE);
        // general.setText("General");
        /* Crawler sub-property */
        // crawler = new TreeItem(tree, SWT.NONE);
        // crawler.setText("Crawler");
        /* Browser sub-property */
        // browser = new TreeItem(tree, SWT.NONE);
        // browser.setText("Browser");
        /* Connection sub-property */
        connection = new TreeItem(tree, SWT.NONE);
        connection.setText("Connection");
        /* System Tray sub-property */
        if (SettingsRegistry.useSystemTray()) {
            // if (!WidgetShop.isset(general)) {
            // general = new TreeItem(tree, SWT.NONE);
            // general.setText("General");
            // }
            systemTray = new TreeItem(tree, SWT.NONE);
            systemTray.setText("System Tray");
        }
        /* View properties */
        view = new TreeItem(tree, SWT.NONE);
        view.setText("View");
        /* Browser tab sub-property */
        browserTab = new TreeItem(view, SWT.NONE);
        browserTab.setText("Internal Browser");
        /* Log tab sub-property */
        // logTab = new TreeItem(view, SWT.NONE);
        // logTab.setText("Debug Log");
        // logTab.setForeground(ColourUtil.gray);
        /* Status tab sub-property */
        // statusTab = new TreeItem(view, SWT.NONE);
        // statusTab.setText("Status");
        // statusTab.setForeground(ColourUtil.gray);
        /* Transfer tab sub-property */
        transferTab = new TreeItem(view, SWT.NONE);
        transferTab.setText("Transfer");
        /* Query tab sub-property */
        queryTab = new TreeItem(view, SWT.NONE);
        queryTab.setText("Queries");
        /* Services sub-property */
        services = new TreeItem(tree, SWT.NONE);
        services.setText("Services");
        /* Arxiv sub-property */
        arxiv = new TreeItem(services, SWT.NONE);
        arxiv.setText("ArXiv");
        /* DOI sub-property */
        doi = new TreeItem(services, SWT.NONE);
        doi.setText("DOI");
        /* Cite Seer sub-property */
        // citeSeer = new TreeItem(services, SWT.NONE);
        // citeSeer.setText("Cite Seer");
        /* Google Scholar sub-property */
        googleDesktop = new TreeItem(services, SWT.NONE);
        googleDesktop.setText("Google Desktop Search");
        /* Google Scholar sub-property */
        google = new TreeItem(services, SWT.NONE);
        google.setText("Google Web Search");
        /* Google Scholar sub-property */
        googleScholar = new TreeItem(services, SWT.NONE);
        googleScholar.setText("Google Scholar");
        /* Plos Journals sub-property */
        plosjournals = new TreeItem(services, SWT.NONE);
        plosjournals.setText("Plos Journals");
        /* PubMed sub-property */
        pubmed = new TreeItem(services, SWT.NONE);
        pubmed.setText("PubMed");
        /* PubMed Central sub-property */
        pubmedCentral = new TreeItem(services, SWT.NONE);
        pubmedCentral.setText("PubMed Central");
        /* Scirus sub-property */
        scirus = new TreeItem(services, SWT.NONE);
        scirus.setText("Scirus");
        /* Terrier sub-property */
        terrier = new TreeItem(services, SWT.NONE);
        terrier.setText("Terrier");
        /* WOK sub-property */
        webofknowledge = new TreeItem(services, SWT.NONE);
        webofknowledge.setText("Web Of Knowledge");
        /* Yahoo sub-property */
        yahoo = new TreeItem(services, SWT.NONE);
        yahoo.setText("Yahoo Web Search");
        // if (WidgetShop.isset(general))
        // general.setExpanded(true);
        if (WidgetUtil.isset(view)) {
            view.setExpanded(true);
        }
        if (WidgetUtil.isset(services)) {
            services.setExpanded(true);
        }
        if (StringUtil.isset(selectionText)) {
            restoreSelection(selectionText, tree.getItems());
        }
    }
    private void renewPropertyPage(String title) {
        if (activePropertyPage != null) {
            activePropertyPage.updatePropertiesChangeManager();
            activePropertyPage.dispose();
        }
        if (labelPrefTitle == null) {
            labelPrefTitle = new Label(prefTitleHolder, SWT.LEFT);
            labelPrefTitle.setBackground(GUI.display
                    .getSystemColor(SWT.COLOR_WHITE));
            labelPrefTitle.setLayoutData(new GridData(SWT.FILL, SWT.CENTER,
                    true, false));
            labelPrefTitle.setFont(FontUtil.dialogBoldFont);
        }
        if (labelImgHolder == null) {
            labelImgHolder = new Label(prefTitleHolder, SWT.NONE);
            labelImgHolder.setBackground(GUI.display
                    .getSystemColor(SWT.COLOR_WHITE));
            labelImgHolder.setImage(PaintUtil.iconBlueStripes);
            labelImgHolder.setLayoutData(new GridData(SWT.END, SWT.END, false,
                    false));
        }
        labelPrefTitle.setText(title);
        labelPrefTitle.update();
        labelImgHolder.update();
        prefTitleHolder.layout();
        contentHolder.layout();
    }
    private void restoreSelection(String selectionText, TreeItem items[]) {
        for (TreeItem item : items) {
            if (selectionText.equals(item.getText())) {


Please complete the code given below. 
/*
 * ATLauncher - https://github.com/ATLauncher/ATLauncher
 * Copyright (C) 2013 ATLauncher
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.atlauncher.gui.tabs;
import com.atlauncher.App;
import com.atlauncher.data.Instance;
import com.atlauncher.data.Language;
import com.atlauncher.evnt.listener.RelocalizationListener;
import com.atlauncher.evnt.manager.RelocalizationManager;
import com.atlauncher.gui.card.InstanceCard;
import com.atlauncher.gui.card.NilCard;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.regex.Pattern;
/**
 * TODO: Rewrite this for better loading
 */
public class InstancesTab extends JPanel implements Tab, RelocalizationListener {
    private static final long serialVersionUID = -969812552965390610L;
    private JPanel topPanel;
    private JButton clearButton;
    private JTextField searchBox;
    private JButton searchButton;
    private JCheckBox hasUpdate;
    private JLabel hasUpdateLabel;
    private String searchText = null;
    private boolean isUpdate = false;
    private JPanel panel;
    private JScrollPane scrollPane;
    private int currentPosition = 0;
    
    private NilCard nilCard;
    public InstancesTab() {
        setLayout(new BorderLayout());
        loadContent(false);
        RelocalizationManager.addListener(this);
    }
    public void loadContent(boolean keepFilters) {
        topPanel = new JPanel();
        topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        clearButton = new JButton(Language.INSTANCE.localize("common.clear"));
        clearButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                searchBox.setText("");
                hasUpdate.setSelected(false);
                reload();
            }
        });
        topPanel.add(clearButton);
        searchBox = new JTextField(16);
        if (keepFilters) {
            searchBox.setText(this.searchText);
        }
        searchBox.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                if (e.getKeyChar() == KeyEvent.VK_ENTER) {
                    reload();
                }
            }
        });
        topPanel.add(searchBox);
        searchButton = new JButton(Language.INSTANCE.localize("common.search"));
        searchButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                reload();
            }
        });
        topPanel.add(searchButton);
        hasUpdate = new JCheckBox();
        hasUpdate.setSelected(isUpdate);
        hasUpdate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                reload();
            }
        });
        topPanel.add(hasUpdate);
        hasUpdateLabel = new JLabel(Language.INSTANCE.localize("instance.hasupdate"));
        topPanel.add(hasUpdateLabel);
        add(topPanel, BorderLayout.NORTH);
        panel = new JPanel();
        scrollPane = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane
                .HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.getVerticalScrollBar().setUnitIncrement(16);
        add(scrollPane, BorderLayout.CENTER);
        panel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = gbc.gridy = 0;
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        int count = 0;
        for (Instance instance : App.settings.getInstancesSorted()) {
            if (instance.canPlay()) {
                if (keepFilters) {
                    boolean showInstance = true;
                    if (searchText != null) {
                        if (!Pattern.compile(Pattern.quote(searchText), Pattern.CASE_INSENSITIVE).matcher(instance
                                .getName()).find()) {
                            showInstance = false;
                        }
                    }
                    if (isUpdate) {
                        if (!instance.hasUpdate()) {
                            showInstance = false;
                        }
                    }
                    if (showInstance) {
                        panel.add(new InstanceCard(instance), gbc);
                        gbc.gridy++;
                        count++;
                    }
                } else {
                    panel.add(new InstanceCard(instance), gbc);
                    gbc.gridy++;
                    count++;
                }
            }
        }
        if (count == 0) {
            nilCard = new NilCard(Language.INSTANCE.localizeWithReplace("instance.nodisplay", "\n\n"));
            panel.add(nilCard, gbc);
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                scrollPane.getVerticalScrollBar().setValue(currentPosition);
            }
        });
    }
    public void reload() {
        this.currentPosition = scrollPane.getVerticalScrollBar().getValue();
        this.searchText = searchBox.getText();
        this.isUpdate = hasUpdate.isSelected();
        if (this.searchText.isEmpty()) {
            this.searchText = null;
        }
        removeAll();
        loadContent(true);
        validate();
        repaint();
        searchBox.requestFocus();
    }
    @Override
    public String getTitle() {
        return Language.INSTANCE.localize("tabs.instances");
    }
    @Override
    public void onRelocalization() {
        clearButton.setText(Language.INSTANCE.localize("common.clear"));
        searchButton.setText(Language.INSTANCE.localize("common.search"));
        hasUpdateLabel.setText(Language.INSTANCE.localize("instance.hasupdate"));
        


Please complete the code given below. 
package name.vbraun.view.write;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.LinkedList;
import java.util.UUID;
import com.write.Quill.artist.Artist;
import junit.framework.Assert;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.Uri;
import android.util.FloatMath;
import android.util.Log;
import android.widget.ImageButton;
import android.widget.Toast;
public class GraphicsImage extends GraphicsControlpoint {
	private static final String TAG = "GraphicsImage";
	private Controlpoint bottom_left, bottom_right, top_left, top_right,
			center;
	private final Paint paint = new Paint();
	private final Paint outline = new Paint();
	private final Rect rect = new Rect();
	private final RectF rectF = new RectF();
	private Bitmap bitmap = null;
	private File file = null;
	private int height, width;
	private float sqrtAspect;
	public enum FileType {
		FILETYPE_NONE, FILETYPE_PNG, FILETYPE_JPG
	}
	
	public static String getImageFileExt(FileType fileType) {
		if (fileType == FileType.FILETYPE_JPG) {
			return ".jpg";
		} else if (fileType == FileType.FILETYPE_PNG) {
			return ".png";
		} else {
			Assert.fail();
			return null;
		}
	}
	
	public static FileType getImageFileType(String fileName) {
		for (FileType t : FileType.values()) {
			if (t == FileType.FILETYPE_NONE)
				continue;
			String ext = getImageFileExt(t);
			if (fileName.endsWith(ext))
				return t;
		}
		return FileType.FILETYPE_NONE;
	}
	/**
	 * Helper to construct a file name out of uuid and file type
	 * @param uuid
	 * @param fileType
	 * @return
	 */
	public static String getImageFileName(UUID uuid, FileType fileType) {
		return uuid.toString() + getImageFileExt(fileType);
	}
	public String getFileName() {
		return file.getAbsolutePath();
	}
	
	// persistent data
	protected UUID uuid = null;
	protected boolean constrainAspect = true;
	protected Rect cropRect = new Rect();
	public UUID getUuid() {
		if (uuid == null)
			uuid = UUID.randomUUID();
		return uuid;
	}
	public Uri getFileUri() {
		if (file == null)
			return null;   // no picture selected yet
		else
			return Uri.fromFile(file);
	}
	
	public File getFile() {
		return file;
	}
	public boolean getConstrainAspect() {
		return constrainAspect;
	}
	
	public FileType getFileType() {
		return getImageFileType(file.getName());
	}
	/**
	 * Construct a new image
	 * 
	 * @param transform
	 *            The current transformation
	 * @param x
	 *            Screen x coordinate
	 * @param y
	 *            Screen y coordinate
	 * @param penThickness
	 * @param penColor
	 */
	protected GraphicsImage(Transformation transform, float x, float y) {
		super(Tool.IMAGE);
		setTransform(transform);
		bottom_left = new Controlpoint(transform, x, y);
		bottom_right = new Controlpoint(transform, x, y);
		top_left = new Controlpoint(transform, x, y);
		top_right = new Controlpoint(transform, x, y);
		center = new Controlpoint(transform, x, y);
		controlpoints.add(bottom_left);
		controlpoints.add(bottom_right);
		controlpoints.add(top_left);
		controlpoints.add(top_right);
		controlpoints.add(center);
		init();
	}
	
	/**
	 * The copy constructor
	 * @param image
	 * @param dir the directory to copy the image file to
	 */
	protected GraphicsImage(final GraphicsImage image, File dir) {
		super(image);
		bottom_left = new Controlpoint(image.bottom_left);
		bottom_right = new Controlpoint(image.bottom_right);
		top_left = new Controlpoint(image.top_left);
		top_right = new Controlpoint(image.top_right);
		center = new Controlpoint(image.center);
		controlpoints.add(bottom_left);
		controlpoints.add(bottom_right);
		controlpoints.add(top_left);
		controlpoints.add(top_right);
		controlpoints.add(center);
		constrainAspect = image.constrainAspect;
		init();
		if (image.getFile() == null) 
			return;
		final String fileName = getImageFileName(getUuid(), image.getFileType());
		file = new File(dir, fileName);
		com.write.Quill.image.Util.copyfile(image.getFile(), file);
	}
	private void init() {
		paint.setARGB(0xff, 0x5f, 0xff, 0x5f);
		paint.setStyle(Style.FILL);
		paint.setStrokeWidth(0);
		paint.setAntiAlias(true);
		paint.setStrokeCap(Paint.Cap.ROUND);
		outline.setARGB(0xff, 0x0, 0xaa, 0x0);
		outline.setStyle(Style.STROKE);
		outline.setStrokeWidth(4);
		outline.setAntiAlias(true);
		outline.setStrokeCap(Paint.Cap.ROUND);
	}
	@Override
	protected Controlpoint initialControlpoint() {
		return bottom_right;
	}
	@Override
	public boolean intersects(RectF screenRect) {
		return false;
	}
	@Override
	public void draw(Canvas c, RectF bounding_box) {
		if (file != null && bitmap == null)
			try {
				loadBitmap();
			} catch (IOException e) {
				Log.e(TAG, "loading bitmap: "+e.getMessage());
			}
		
		computeScreenRect();
		c.clipRect(0, 0, c.getWidth(), c.getHeight(), android.graphics.Region.Op.REPLACE);
		if (bitmap == null) {
			c.drawRect(rect, paint);
			c.drawRect(rect, outline);
		} else {
			c.drawBitmap(bitmap, null, rect, null);
		}
	}
	private Controlpoint oppositeControlpoint(Controlpoint point) {
		if (point == bottom_right)
			return top_left;
		if (point == bottom_left)
			return top_right;
		if (point == top_right)
			return bottom_left;
		if (point == top_left)
			return bottom_right;
		if (point == center)
			return center;
		Assert.fail("Unreachable");
		return null;
	}
	private final static float minDistancePixel = 30;
	@Override
	void controlpointMoved(Controlpoint point) {
		super.controlpointMoved(point);
		if (point == center) {
			float width2 = (bottom_right.x - bottom_left.x) / 2;
			float height2 = (top_right.y - bottom_right.y) / 2;
			bottom_right.y = bottom_left.y = center.y - height2;
			top_right.y = top_left.y = center.y + height2;
			bottom_right.x = top_right.x = center.x + width2;
			bottom_left.x = top_left.x = center.x - width2;
		} else {
			Controlpoint opposite = oppositeControlpoint(point);
			float dx = opposite.x - point.x;
			float dy = opposite.y - point.y;
			float minDistance = minDistancePixel / scale;
			if (-minDistance <= dx && dx <= minDistance) {
				float sgn = Math.signum(dx);
				opposite.x = point.x + sgn * minDistance;
				dx = sgn * minDistance;
			}
			if (-minDistance <= dy && dy <= minDistance) {
				float sgn = Math.signum(dy);
				opposite.y = point.y + sgn * minDistance;
				dy = sgn *minDistance;
			}
			if (constrainAspect && bitmap != null) {
				float r = (Math.abs(dx)+Math.abs(dy))/2;
				dx = r * sqrtAspect * Math.signum(dx);
				dy = r / sqrtAspect * Math.signum(dy);
				// Log.d(TAG, "move "+dx + " "+dy + " " + r + " "+(sqrtAspect*sqrtAspect));
			}
			rectF.bottom = opposite.y;
			rectF.top = opposite.y - dy;
			rectF.left = opposite.x;
			rectF.right = opposite.x - dx;
			rectF.sort();
			bottom_right.y = bottom_left.y = rectF.bottom;
			top_right.y = top_left.y = rectF.top;
			bottom_right.x = top_right.x = rectF.right;
			bottom_left.x = top_left.x = rectF.left;
			center.x = rectF.left + (rectF.right - rectF.left) / 2;
			center.y = rectF.bottom + (rectF.top - rectF.bottom) / 2;
		}
	}
	private void computeScreenRect() {
		rectF.bottom = bottom_left.screenY();
		rectF.top = top_left.screenY();
		rectF.left = bottom_left.screenX();
		rectF.right = bottom_right.screenX();
		rectF.sort();
		rectF.round(rect);
	}
	public void writeToStream(DataOutputStream out) throws IOException {
		out.writeInt(1);  // protocol #1
		out.writeUTF(uuid.toString());
		out.writeFloat(top_left.x);
		out.writeFloat(top_right.x);
		out.writeFloat(top_left.y);
		out.writeFloat(bottom_left.y);
		out.writeBoolean(constrainAspect);
	}
	public GraphicsImage(DataInputStream in, File dir) throws IOException {
		super(Tool.IMAGE);
		int version = in.readInt();
		if (version > 1)
			throw new IOException("Unknown image version!");
		uuid = UUID.fromString(in.readUTF());
		float left   = in.readFloat(); 
		float right  = in.readFloat();
		float top    = in.readFloat();
		float bottom = in.readFloat();  		
		constrainAspect = in.readBoolean();
		
		bottom_left = new Controlpoint(transform, left, bottom);
		bottom_right = new Controlpoint(transform, right, bottom);
		top_left = new Controlpoint(transform, left, top);
		top_right = new Controlpoint(transform, right, top);
		center = new Controlpoint(transform, (left+right)/2, (top+bottom)/2);
		controlpoints.add(bottom_left);
		controlpoints.add(bottom_right);
		controlpoints.add(top_left);
		controlpoints.add(top_right);
		controlpoints.add(center);
		init();
		file = new File(dir, getImageFileName(uuid, FileType.FILETYPE_JPG));
	}
	@Override
	public void render(Artist artist) {
		artist.imageJpeg(file, top_left.x, top_right.x, top_left.y, bottom_left.y);
	}
	public boolean checkFileName(String fileName) {
		FileType fileType = getImageFileType(fileName);
		return fileName.endsWith(getImageFileName(uuid, fileType));
	}
	
	public void setFile(String fileName, boolean constrainAspect) {
		// file = new File("/mnt/sdcard/d5efe912-4b03-4ed7-a124-bff4984691d6.jpg");
		if (!checkFileName(fileName)) {
			Log.e(TAG, "filename must be uuid.ext");
		}
		file = new File(fileName);
		try {
			loadBitmap();
		} catch (IOException e) {
			Log.e(TAG, "Unable to load file " + file.toString() + " (missing?");
		}
		this.constrainAspect = constrainAspect;
		if (constrainAspect) {
			float w = top_right.x - top_left.x;
			float h = bottom_right.y - top_right.y;


Please complete the code given below. 
import gtk
import gobject
import pygame
import pygame.event 
class _MockEvent(object):
    def __init__(self, keyval):
        self.keyval = keyval
class Translator(object):
    key_trans = {
        'Alt_L': pygame.K_LALT,
        'Alt_R': pygame.K_RALT,
        'Control_L': pygame.K_LCTRL,
        'Control_R': pygame.K_RCTRL,
        'Shift_L': pygame.K_LSHIFT,
        'Shift_R': pygame.K_RSHIFT,
        'Super_L': pygame.K_LSUPER,
        'Super_R': pygame.K_RSUPER,
        'KP_Page_Up' : pygame.K_KP9, 
        'KP_Page_Down' : pygame.K_KP3,
        'KP_End' : pygame.K_KP1, 
        'KP_Home' : pygame.K_KP7,
        'KP_Up' : pygame.K_KP8,
        'KP_Down' : pygame.K_KP2,
        'KP_Left' : pygame.K_KP4,
        'KP_Right' : pygame.K_KP6,
        'numbersign' : pygame.K_HASH,
        'percent' : ord('%'),
        'exclam' : pygame.K_EXCLAIM,
	'asciicircum' : pygame.K_CARET,
        'parenleft' : pygame.K_LEFTPAREN,
        'parenright' : pygame.K_RIGHTPAREN,
        'braceleft' : ord('{'),
        'braceright' : ord('}'),
        'bracketleft' : pygame.K_LEFTBRACKET,
        'bracketright' : pygame.K_RIGHTBRACKET,
        'apostrophe' : ord('\''),
        'equal' : pygame.K_EQUALS,
        'grave' : pygame.K_BACKQUOTE,
        'Caps_Lock' : pygame.K_CAPSLOCK,
        'Page_Up' : pygame.K_PAGEUP,
        'Page_Down' : pygame.K_PAGEDOWN,
        'Num_Lock' : pygame.K_NUMLOCK,
        'Bar' : ord('|')
    }
    
    mod_map = {
        pygame.K_LALT: pygame.KMOD_LALT,
        pygame.K_RALT: pygame.KMOD_RALT,
        pygame.K_LCTRL: pygame.KMOD_LCTRL,
        pygame.K_RCTRL: pygame.KMOD_RCTRL,
        pygame.K_LSHIFT: pygame.KMOD_LSHIFT,
        pygame.K_RSHIFT: pygame.KMOD_RSHIFT,
    }
    
    def __init__(self, mainwindow, inner_evb):
        """Initialise the Translator with the windows to which to listen"""
        self._mainwindow = mainwindow
        self._inner_evb = inner_evb
        # Enable events
        # (add instead of set here because the main window is already realized)
        self._mainwindow.add_events(
            gtk.gdk.KEY_PRESS_MASK | \
            gtk.gdk.KEY_RELEASE_MASK | \
            gtk.gdk.VISIBILITY_NOTIFY_MASK
        )
        
        self._inner_evb.set_events(
            gtk.gdk.POINTER_MOTION_MASK | \
            gtk.gdk.POINTER_MOTION_HINT_MASK | \
            gtk.gdk.BUTTON_MOTION_MASK | \
            gtk.gdk.BUTTON_PRESS_MASK | \
            gtk.gdk.BUTTON_RELEASE_MASK
        )
        self._mainwindow.set_flags(gtk.CAN_FOCUS)
        self._inner_evb.set_flags(gtk.CAN_FOCUS)
        
        # Callback functions to link the event systems
        self._mainwindow.connect('unrealize', self._quit_cb)
        self._mainwindow.connect('visibility_notify_event', self._visibility)
        self._inner_evb.connect('key_press_event', self._keydown_cb)
        self._inner_evb.connect('key_release_event', self._keyup_cb)
        self._inner_evb.connect('button_press_event', self._mousedown_cb)
        self._inner_evb.connect('button_release_event', self._mouseup_cb)
        self._inner_evb.connect('motion-notify-event', self._mousemove_cb)
        self._inner_evb.connect('expose-event', self._expose_cb)
        self._inner_evb.connect('configure-event', self._resize_cb)
        self._inner_evb.connect('screen-changed', self._screen_changed_cb)
        
        # Internal data
        self.__stopped = False
        self.__keystate = [0] * 323
        self.__button_state = [0,0,0]
        self.__mouse_pos = (0,0)
        self.__repeat = (None, None)
        self.__held = set()
        self.__held_time_left = {}
        self.__held_last_time = {}
        self.__held_last_value = {}
        self.__tick_id = None
    def hook_pygame(self):
        pygame.key.get_pressed = self._get_pressed
        pygame.key.set_repeat = self._set_repeat
        pygame.mouse.get_pressed = self._get_mouse_pressed
        pygame.mouse.get_pos = self._get_mouse_pos
        
    def _visibility(self, widget, event):
        if pygame.display.get_init():
            pygame.event.post(pygame.event.Event(pygame.VIDEOEXPOSE))
        return False
        
    def _expose_cb(self, widget, event):
        if pygame.display.get_init():
            pygame.event.post(pygame.event.Event(pygame.VIDEOEXPOSE))
        return True
    def _resize_cb(self, widget, event):
        evt = pygame.event.Event(pygame.VIDEORESIZE, 
                                 size=(event.width,event.height), width=event.width, height=event.height)
        pygame.event.post(evt)
        return False # continue processing
        
    def _screen_changed_cb(self, widget, event):
        if pygame.display.get_init():
            pygame.event.post(pygame.event.Event(pygame.VIDEOEXPOSE))
    def _quit_cb(self, data=None):
        self.__stopped = True
        pygame.event.post(pygame.event.Event(pygame.QUIT))
    def _keydown_cb(self, widget, event):
        key = event.hardware_keycode
        keyval = event.keyval
        if key in self.__held:
            return True
        else:
            if self.__repeat[0] is not None:
                self.__held_last_time[key] = pygame.time.get_ticks()
                self.__held_time_left[key] = self.__repeat[0]
                self.__held_last_value[key] = keyval
            self.__held.add(key)
        return self._keyevent(widget, event, pygame.KEYDOWN)
        
    def _keyup_cb(self, widget, event):
        key = event.hardware_keycode
        if self.__repeat[0] is not None:
            if key in self.__held:
                # This is possibly false if set_repeat() is called with a key held
                del self.__held_time_left[key]
                del self.__held_last_time[key]
                del self.__held_last_value[key]
        self.__held.discard(key)
        return self._keyevent(widget, event, pygame.KEYUP)
        
    def _keymods(self):
        mod = 0
        for key_val, mod_val in self.mod_map.iteritems():
            mod |= self.__keystate[key_val] and mod_val
        return mod
        
    def _keyevent(self, widget, event, type):
        key = gtk.gdk.keyval_name(event.keyval)
        if key is None:
            # No idea what this key is.
            return False 
        
        keycode = None
        if key in self.key_trans:
            keycode = self.key_trans[key]
        elif hasattr(pygame, 'K_'+key.upper()):
            keycode = getattr(pygame, 'K_'+key.upper())
        elif hasattr(pygame, 'K_'+key.lower()):
            keycode = getattr(pygame, 'K_'+key.lower())
        elif key == 'XF86Start':
            # view source request, specially handled...
            self._mainwindow.view_source()
        else:
            print 'Key %s unrecognized' % key
            
        if keycode is not None:
            if type == pygame.KEYDOWN:
                mod = self._keymods()
            self.__keystate[keycode] = type == pygame.KEYDOWN
            if type == pygame.KEYUP:
                mod = self._keymods()
            ukey = unichr(gtk.gdk.keyval_to_unicode(event.keyval))
            if ukey == '\000':
                ukey = ''
            evt = pygame.event.Event(type, key=keycode, unicode=ukey, mod=mod)
            self._post(evt)
            
        return True
    def _get_pressed(self):
        return self.__keystate
    def _get_mouse_pressed(self):
        return self.__button_state
    def _mousedown_cb(self, widget, event):
        self.__button_state[event.button-1] = 1
        widget.grab_focus()
        return self._mouseevent(widget, event, pygame.MOUSEBUTTONDOWN)
    def _mouseup_cb(self, widget, event):
        self.__button_state[event.button-1] = 0
        return self._mouseevent(widget, event, pygame.MOUSEBUTTONUP)
        
    def _mouseevent(self, widget, event, type):
        evt = pygame.event.Event(type, button=event.button, pos=(event.x, event.y))
        self._post(evt)
        return True
        
    def _mousemove_cb(self, widget, event):
        # From http://www.learningpython.com/2006/07/25/writing-a-custom-widget-using-pygtk/
        # if this is a hint, then let's get all the necessary 
        # information, if not it's all we need.
        if event.is_hint:
            x, y, state = event.window.get_pointer()
        else:
            x = event.x
            y = event.y
            state = event.state
        rel = (x - self.__mouse_pos[0], y - self.__mouse_pos[1])
        self.__mouse_pos = (x, y)
        
        self.__button_state = [
            state & gtk.gdk.BUTTON1_MASK and 1 or 0,
            state & gtk.gdk.BUTTON2_MASK and 1 or 0,
            state & gtk.gdk.BUTTON3_MASK and 1 or 0,
        ]
        
        evt = pygame.event.Event(pygame.MOUSEMOTION,
                                 pos=self.__mouse_pos, rel=rel, buttons=self.__button_state)
        self._post(evt)
        return True
        
    def _tick_cb(self):
        cur_time = pygame.time.get_ticks()
        for key in self.__held:
            delta = cur_time - self.__held_last_time[key] 
            self.__held_last_time[key] = cur_time
            
            self.__held_time_left[key] -= delta
            if self.__held_time_left[key] <= 0:
                self.__held_time_left[key] = self.__repeat[1]
                self._keyevent(None, _MockEvent(self.__held_last_value[key]), pygame.KEYDOWN)
                
        return True
        
    def _set_repeat(self, delay=None, interval=None):
        if delay is not None and self.__repeat[0] is None:


Please complete the code given below. 
import json
import os
import sys
from datetime import datetime, timedelta
import wptserve
from wptserve import sslutils
from . import environment as env
from . import instruments
from . import mpcontext
from . import products
from . import testloader
from . import wptcommandline
from . import wptlogging
from . import wpttest
from mozlog import capture, handlers
from .font import FontInstaller
from .testrunner import ManagerGroup
here = os.path.dirname(__file__)
logger = None
"""Runner for web-platform-tests
The runner has several design goals:
* Tests should run with no modification from upstream.
* Tests should be regarded as "untrusted" so that errors, timeouts and even
  crashes in the tests can be handled without failing the entire test run.
* For performance tests can be run in multiple browsers in parallel.
The upstream repository has the facility for creating a test manifest in JSON
format. This manifest is used directly to determine which tests exist. Local
metadata files are used to store the expected test results.
"""
def setup_logging(*args, **kwargs):
    global logger
    logger = wptlogging.setup(*args, **kwargs)
    return logger
def get_loader(test_paths, product, debug=None, run_info_extras=None, chunker_kwargs=None,
               test_groups=None, **kwargs):
    if run_info_extras is None:
        run_info_extras = {}
    run_info = wpttest.get_run_info(kwargs["run_info"], product,
                                    browser_version=kwargs.get("browser_version"),
                                    browser_channel=kwargs.get("browser_channel"),
                                    verify=kwargs.get("verify"),
                                    debug=debug,
                                    extras=run_info_extras,
                                    enable_webrender=kwargs.get("enable_webrender"))
    test_manifests = testloader.ManifestLoader(test_paths, force_manifest_update=kwargs["manifest_update"],
                                               manifest_download=kwargs["manifest_download"]).load()
    manifest_filters = []
    include = kwargs["include"]
    if kwargs["include_file"]:
        include = include or []
        include.extend(testloader.read_include_from_file(kwargs["include_file"]))
    if test_groups:
        include = testloader.update_include_for_groups(test_groups, include)
    if include or kwargs["exclude"] or kwargs["include_manifest"] or kwargs["default_exclude"]:
        manifest_filters.append(testloader.TestFilter(include=include,
                                                      exclude=kwargs["exclude"],
                                                      manifest_path=kwargs["include_manifest"],
                                                      test_manifests=test_manifests,
                                                      explicit=kwargs["default_exclude"]))
    ssl_enabled = sslutils.get_cls(kwargs["ssl_type"]).ssl_enabled
    h2_enabled = wptserve.utils.http2_compatible()
    test_loader = testloader.TestLoader(test_manifests,
                                        kwargs["test_types"],
                                        run_info,
                                        manifest_filters=manifest_filters,
                                        chunk_type=kwargs["chunk_type"],
                                        total_chunks=kwargs["total_chunks"],
                                        chunk_number=kwargs["this_chunk"],
                                        include_https=ssl_enabled,
                                        include_h2=h2_enabled,
                                        include_webtransport_h3=kwargs["enable_webtransport_h3"],
                                        skip_timeout=kwargs["skip_timeout"],
                                        skip_implementation_status=kwargs["skip_implementation_status"],
                                        chunker_kwargs=chunker_kwargs)
    return run_info, test_loader
def list_test_groups(test_paths, product, **kwargs):
    env.do_delayed_imports(logger, test_paths)
    run_info_extras = products.Product(kwargs["config"], product).run_info_extras(**kwargs)
    run_info, test_loader = get_loader(test_paths, product,
                                       run_info_extras=run_info_extras, **kwargs)
    for item in sorted(test_loader.groups(kwargs["test_types"])):
        print(item)
def list_disabled(test_paths, product, **kwargs):
    env.do_delayed_imports(logger, test_paths)
    rv = []
    run_info_extras = products.Product(kwargs["config"], product).run_info_extras(**kwargs)
    run_info, test_loader = get_loader(test_paths, product,
                                       run_info_extras=run_info_extras, **kwargs)
    for test_type, tests in test_loader.disabled_tests.items():
        for test in tests:
            rv.append({"test": test.id, "reason": test.disabled()})
    print(json.dumps(rv, indent=2))
def list_tests(test_paths, product, **kwargs):
    env.do_delayed_imports(logger, test_paths)
    run_info_extras = products.Product(kwargs["config"], product).run_info_extras(**kwargs)
    run_info, test_loader = get_loader(test_paths, product,
                                       run_info_extras=run_info_extras, **kwargs)
    for test in test_loader.test_ids:
        print(test)
def get_pause_after_test(test_loader, **kwargs):
    if kwargs["pause_after_test"] is None:
        if kwargs["repeat_until_unexpected"]:
            return False
        if kwargs["headless"]:
            return False
        if kwargs["debug_test"]:
            return True
        tests = test_loader.tests
        is_single_testharness = (sum(len(item) for item in tests.values()) == 1 and
                                 len(tests.get("testharness", [])) == 1)
        if kwargs["repeat"] == 1 and kwargs["rerun"] == 1 and is_single_testharness:
            return True
        return False
    return kwargs["pause_after_test"]
def run_test_iteration(test_status, test_loader, test_source_kwargs, test_source_cls, run_info,
                       recording, test_environment, product, run_test_kwargs):
    """Runs the entire test suite.
    This is called for each repeat run requested."""
    tests = []
    for test_type in test_loader.test_types:
        tests.extend(test_loader.tests[test_type])
    try:
        test_groups = test_source_cls.tests_by_group(
            tests, **test_source_kwargs)
    except Exception:
        logger.critical("Loading tests failed")
        return False
    logger.suite_start(test_groups,
                       name='web-platform-test',
                       run_info=run_info,
                       extra={"run_by_dir": run_test_kwargs["run_by_dir"]})
    for test_type in run_test_kwargs["test_types"]:
        logger.info(f"Running {test_type} tests")
        browser_cls = product.get_browser_cls(test_type)
        browser_kwargs = product.get_browser_kwargs(logger,
                                                    test_type,
                                                    run_info,
                                                    config=test_environment.config,
                                                    num_test_groups=len(test_groups),
                                                    **run_test_kwargs)
        executor_cls = product.executor_classes.get(test_type)
        executor_kwargs = product.get_executor_kwargs(logger,
                                                      test_type,
                                                      test_environment,
                                                      run_info,
                                                      **run_test_kwargs)
        if executor_cls is None:
            logger.error(f"Unsupported test type {test_type} for product {product.name}")
            continue
        for test in test_loader.disabled_tests[test_type]:
            logger.test_start(test.id)
            logger.test_end(test.id, status="SKIP")
            test_status.skipped += 1
        if test_type == "testharness":
            run_tests = {"testharness": []}
            for test in test_loader.tests["testharness"]:
                if ((test.testdriver and not executor_cls.supports_testdriver) or
                        (test.jsshell and not executor_cls.supports_jsshell)):
                    logger.test_start(test.id)
                    logger.test_end(test.id, status="SKIP")
                    test_status.skipped += 1
                else:
                    run_tests["testharness"].append(test)
        else:
            run_tests = test_loader.tests
        recording.pause()
        with ManagerGroup("web-platform-tests",
                          run_test_kwargs["processes"],
                          test_source_cls,
                          test_source_kwargs,
                          browser_cls,
                          browser_kwargs,
                          executor_cls,
                          executor_kwargs,
                          run_test_kwargs["rerun"],
                          run_test_kwargs["pause_after_test"],
                          run_test_kwargs["pause_on_unexpected"],
                          run_test_kwargs["restart_on_unexpected"],
                          run_test_kwargs["debug_info"],
                          not run_test_kwargs["no_capture_stdio"],
                          recording=recording) as manager_group:
            try:
                manager_group.run(test_type, run_tests)
            except KeyboardInterrupt:
                logger.critical("Main thread got signal")
                manager_group.stop()
                raise
            test_status.total_tests += manager_group.test_count()
            test_status.unexpected += manager_group.unexpected_count()
            test_status.unexpected_pass += manager_group.unexpected_pass_count()
    return True
def evaluate_runs(test_status, run_test_kwargs):
    """Evaluates the test counts after the given number of repeat runs has finished"""
    if test_status.total_tests == 0:
        if test_status.skipped > 0:
            logger.warning("All requested tests were skipped")
        else:
            if run_test_kwargs["default_exclude"]:
                logger.info("No tests ran")
                return True
            else:
                logger.critical("No tests ran")
                return False
    if test_status.unexpected and not run_test_kwargs["fail_on_unexpected"]:
        logger.info(f"Tolerating {test_status.unexpected} unexpected results")
        return True
    all_unexpected_passed = (test_status.unexpected and
                             test_status.unexpected == test_status.unexpected_pass)
    if all_unexpected_passed and not run_test_kwargs["fail_on_unexpected_pass"]:
        logger.info(f"Tolerating {test_status.unexpected_pass} unexpected results "
                    "because they all PASS")
        return True
    return test_status.unexpected == 0
class TestStatus:
    """Class that stores information on the results of test runs for later reference"""
    def __init__(self):
        self.total_tests = 0
        self.skipped = 0
        self.unexpected = 0
        self.unexpected_pass = 0
        self.repeated_runs = 0
        self.expected_repeated_runs = 0
        self.all_skipped = False
def run_tests(config, test_paths, product, **kwargs):
    """Set up the test environment, load the list of tests to be executed, and
    invoke the remainder of the code to execute tests"""
    mp = mpcontext.get_context()
    if kwargs["instrument_to_file"] is None:
        recorder = instruments.NullInstrument()
    else:
        recorder = instruments.Instrument(kwargs["instrument_to_file"])
    with recorder as recording, capture.CaptureIO(logger,
                                                  not kwargs["no_capture_stdio"],
                                                  mp_context=mp):
        recording.set(["startup"])
        env.do_delayed_imports(logger, test_paths)
        product = products.Product(config, product)
        env_extras = product.get_env_extras(**kwargs)
        product.check_args(**kwargs)
        if kwargs["install_fonts"]:
            env_extras.append(FontInstaller(
                logger,
                font_dir=kwargs["font_dir"],
                ahem=os.path.join(test_paths["/"]["tests_path"], "fonts/Ahem.ttf")
            ))
        recording.set(["startup", "load_tests"])
        test_groups = (testloader.TestGroupsFile(logger, kwargs["test_groups_file"])
                       if kwargs["test_groups_file"] else None)
        (test_source_cls,
         test_source_kwargs,
         chunker_kwargs) = testloader.get_test_src(logger=logger,
                                                   test_groups=test_groups,
                                                   **kwargs)
        run_info, test_loader = get_loader(test_paths,
                                           product.name,
                                           run_info_extras=product.run_info_extras(**kwargs),
                                           chunker_kwargs=chunker_kwargs,
                                           test_groups=test_groups,
                                           **kwargs)
        logger.info("Using %i client processes" % kwargs["processes"])
        test_status = TestStatus()
        repeat = kwargs["repeat"]
        test_status.expected_repeat = repeat
        if len(test_loader.test_ids) == 0 and kwargs["test_list"]:
            logger.critical("Unable to find any tests at the path(s):")
            for path in kwargs["test_list"]:
                logger.critical("  %s" % path)
            logger.critical("Please check spelling and make sure there are tests in the specified path(s).")
            return False, test_status
        kwargs["pause_after_test"] = get_pause_after_test(test_loader, **kwargs)
        ssl_config = {"type": kwargs["ssl_type"],
                      "openssl": {"openssl_binary": kwargs["openssl_binary"]},
                      "pregenerated": {"host_key_path": kwargs["host_key_path"],
                                       "host_cert_path": kwargs["host_cert_path"],
                                       "ca_cert_path": kwargs["ca_cert_path"]}}
        testharness_timeout_multipler = product.get_timeout_multiplier("testharness",
                                                                       run_info,
                                                                       **kwargs)
        mojojs_path = kwargs["mojojs_path"] if kwargs["enable_mojojs"] else None
        recording.set(["startup", "start_environment"])
        with env.TestEnvironment(test_paths,
                                 testharness_timeout_multipler,
                                 kwargs["pause_after_test"],
                                 kwargs["debug_test"],
                                 kwargs["debug_info"],
                                 product.env_options,
                                 ssl_config,
                                 env_extras,
                                 kwargs["enable_webtransport_h3"],
                                 mojojs_path) as test_environment:
            recording.set(["startup", "ensure_environment"])
            try:
                test_environment.ensure_started()
                start_time = datetime.now()
            except env.TestEnvironmentError as e:
                logger.critical("Error starting test environment: %s" % e)
                raise
            recording.set(["startup"])
            max_time = None
            if "repeat_max_time" in kwargs:
                max_time = timedelta(minutes=kwargs["repeat_max_time"])
            repeat_until_unexpected = kwargs["repeat_until_unexpected"]
            # keep track of longest time taken to complete a test suite iteration
            # so that the runs can be stopped to avoid a possible TC timeout.
            longest_iteration_time = timedelta()
            while test_status.repeated_runs < repeat or repeat_until_unexpected:
                # if the next repeat run could cause the TC timeout to be reached,
                # stop now and use the test results we have.
                # Pad the total time by 10% to ensure ample time for the next iteration(s).
                estimate = (datetime.now() +
                            timedelta(seconds=(longest_iteration_time.total_seconds() * 1.1)))
                if not repeat_until_unexpected and max_time and estimate >= start_time + max_time:
                    logger.info(f"Ran {test_status.repeated_runs} of {repeat} iterations.")
                    break
                # begin tracking runtime of the test suite
                iteration_start = datetime.now()
                test_status.repeated_runs += 1
                if repeat_until_unexpected:
                    logger.info(f"Repetition {test_status.repeated_runs}")
                elif repeat > 1:
                    logger.info(f"Repetition {test_status.repeated_runs} / {repeat}")
                iter_success = run_test_iteration(test_status, test_loader, test_source_kwargs,
                                                  test_source_cls, run_info, recording,
                                                  test_environment, product, kwargs)
                # if there were issues with the suite run(tests not loaded, etc.) return
                if not iter_success:
                    return False, test_status
                recording.set(["after-end"])
                logger.info(f"Got {test_status.unexpected} unexpected results, "
                    f"with {test_status.unexpected_pass} unexpected passes")
                logger.suite_end()
                # Note this iteration's runtime
                iteration_runtime = datetime.now() - iteration_start
                # determine the longest test suite runtime seen.
                longest_iteration_time = max(longest_iteration_time,
                                             iteration_runtime)
                if repeat_until_unexpected and test_status.unexpected > 0:
                    break
                if test_status.repeated_runs == 1 and len(test_loader.test_ids) == test_status.skipped:
                    test_status.all_skipped = True
                    break
    # Return the evaluation of the runs and the number of repeated iterations that were run.
    return evaluate_runs(test_status, kwargs), test_status
def check_stability(**kwargs):
    from . import stability
    if kwargs["stability"]:
        logger.warning("--stability is deprecated; please use --verify instead!")
        kwargs['verify_max_time'] = None
        kwargs['verify_chaos_mode'] = False
        kwargs['verify_repeat_loop'] = 0
        kwargs['verify_repeat_restart'] = 10 if kwargs['repeat'] == 1 else kwargs['repeat']
        kwargs['verify_output_results'] = True
    return stability.check_stability(logger,
                                     max_time=kwargs['verify_max_time'],
                                     chaos_mode=kwargs['verify_chaos_mode'],
                                     repeat_loop=kwargs['verify_repeat_loop'],
                                     repeat_restart=kwargs['verify_repeat_restart'],
                                     output_results=kwargs['verify_output_results'],
                                     **kwargs)
def start(**kwargs):
    assert logger is not None
    logged_critical = wptlogging.LoggedAboveLevelHandler("CRITICAL")


Please complete the code given below. 
# -*- coding: utf-8 -*-
"""
This module contains a POI Manager core class which gives capability to mark
points of interest, re-optimise their position, and keep track of sample drift
over time.
Qudi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Qudi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Qudi. If not, see <http://www.gnu.org/licenses/>.
Copyright (c) the Qudi Developers. See the COPYRIGHT.txt file at the
top-level directory of this distribution and at <https://github.com/Ulm-IQO/qudi/>
"""
from qtpy import QtCore
import ctypes   # is a foreign function library for Python. It provides C
                # compatible data types, and allows calling functions in DLLs
                # or shared libraries. It can be used to wrap these libraries
                # in pure Python.
from interface.wavemeter_interface import WavemeterInterface
from core.base import Base
from core.util.mutex import Mutex
class HardwarePull(QtCore.QObject):
    """ Helper class for running the hardware communication in a separate thread. """
    # signal to deliver the wavelength to the parent class
    sig_wavelength = QtCore.Signal(float, float)
    def __init__(self, parentclass):
        super().__init__()
        # remember the reference to the parent class to access functions ad settings
        self._parentclass = parentclass
    def handle_timer(self, state_change):
        """ Threaded method that can be called by a signal from outside to start the timer.
        @param bool state: (True) starts timer, (False) stops it.
        """
        if state_change:
            self.timer = QtCore.QTimer()
            self.timer.timeout.connect(self._measure_thread)
            self.timer.start(self._parentclass._measurement_timing)
        else:
            if hasattr(self, 'timer'):
                self.timer.stop()
    def _measure_thread(self):
        """ The threaded method querying the data from the wavemeter.
        """
        # update as long as the state is busy
        if self._parentclass.getState() == 'running':
            # get the current wavelength from the wavemeter
            temp1=float(self._parentclass._wavemeterdll.GetWavelength(0))
            temp2=float(self._parentclass._wavemeterdll.GetWavelength(0))
            # send the data to the parent via a signal
            self.sig_wavelength.emit(temp1, temp2)
class HighFinesseWavemeter(Base,WavemeterInterface):
    _modclass = 'HighFinesseWavemeter'
    _modtype = 'hardware'
    ## declare connectors
    _out = {'highfinessewavemeter': 'WavemeterInterface'}
    sig_handle_timer = QtCore.Signal(bool)
    #############################################
    # Flags for the external DLL
    #############################################
    # define constants as flags for the wavemeter
    _cCtrlStop                   = ctypes.c_uint16(0x00)
    # this following flag is modified to override every existing file
    _cCtrlStartMeasurment        = ctypes.c_uint16(0x1002)
    _cReturnWavelangthAir        = ctypes.c_long(0x0001)
    _cReturnWavelangthVac        = ctypes.c_long(0x0000)
    def __init__(self, config, **kwargs):
        super().__init__(config=config, **kwargs)
        #locking for thread safety
        self.threadlock = Mutex()
        # the current wavelength read by the wavemeter in nm (vac)
        self._current_wavelength=0.0
        self._current_wavelength2=0.0
        # time between two measurement points of the wavemeter in milliseconds
        if 'measurement_timing' in config.keys():
            self._measurement_timing=config['measurement_timing']
        else:
            self._measurement_timing = 10.
            self.log.warning('No measurement_timing configured, '\
                        'using {} instead.'.format(self._measurement_timing))
    def on_activate(self, e):
        #############################################
        # Initialisation to access external DLL
        #############################################
        try:
            # imports the spectrometer specific function from dll
            self._wavemeterdll = ctypes.windll.LoadLibrary('wlmData.dll')
        except:
            self.log.critical('There is no Wavemeter installed on this '
                    'Computer.\nPlease install a High Finesse Wavemeter and '
                    'try again.')
        # define the use of the GetWavelength function of the wavemeter
#        self._GetWavelength2 = self._wavemeterdll.GetWavelength2
        # return data type of the GetWavelength function of the wavemeter
        self._wavemeterdll.GetWavelength2.restype = ctypes.c_double
        # parameter data type of the GetWavelength function of the wavemeter
        self._wavemeterdll.GetWavelength2.argtypes = [ctypes.c_double]
        # define the use of the GetWavelength function of the wavemeter
#        self._GetWavelength = self._wavemeterdll.GetWavelength
        # return data type of the GetWavelength function of the wavemeter
        self._wavemeterdll.GetWavelength.restype = ctypes.c_double
        # parameter data type of the GetWavelength function of the wavemeter
        self._wavemeterdll.GetWavelength.argtypes = [ctypes.c_double]
        # define the use of the ConvertUnit function of the wavemeter
#        self._ConvertUnit = self._wavemeterdll.ConvertUnit
        # return data type of the ConvertUnit function of the wavemeter
        self._wavemeterdll.ConvertUnit.restype = ctypes.c_double
        # parameter data type of the ConvertUnit function of the wavemeter
        self._wavemeterdll.ConvertUnit.argtypes = [ctypes.c_double, ctypes.c_long, ctypes.c_long]
        # manipulate perdefined operations with simple flags
#        self._Operation = self._wavemeterdll.Operation
        # return data type of the Operation function of the wavemeter
        self._wavemeterdll.Operation.restype = ctypes.c_long
        # parameter data type of the Operation function of the wavemeter
        self._wavemeterdll.Operation.argtypes = [ctypes.c_ushort]
        # create an indepentent thread for the hardware communication
        self.hardware_thread = QtCore.QThread()
        # create an object for the hardware communication and let it live on the new thread
        self._hardware_pull = HardwarePull(self)
        self._hardware_pull.moveToThread(self.hardware_thread)
        # connect the signals in and out of the threaded object
        self.sig_handle_timer.connect(self._hardware_pull.handle_timer)
        self._hardware_pull.sig_wavelength.connect(self.handle_wavelength)
        # start the event loop for the hardware
        self.hardware_thread.start()
    def on_deactivate(self, e):
        if self.getState() != 'idle' and self.getState() != 'deactivated':
            self.stop_acqusition()
        self.hardware_thread.quit()
        self.sig_handle_timer.disconnect()
        self._hardware_pull.sig_wavelength.disconnect()
        try:
            # clean up by removing reference to the ctypes library object
            del self._wavemeterdll
            return 0
        except:
            self.log.error('Could not unload the wlmData.dll of the '
                    'wavemeter.')
    #############################################
    # Methods of the main class
    #############################################
    def handle_wavelength(self, wavelength1, wavelength2):
        """ Function to save the wavelength, when it comes in with a signal.
        """
        self._current_wavelength = wavelength1
        self._current_wavelength2 = wavelength2
    def start_acqusition(self):
        """ Method to start the wavemeter software.
        @return int: error code (0:OK, -1:error)
        Also the actual threaded method for getting the current wavemeter reading is started.
        """
        # first check its status
        if self.getState() == 'running':
            self.log.error('Wavemeter busy')
            return -1
        self.run()
        # actually start the wavemeter
        self._wavemeterdll.Operation(self._cCtrlStartMeasurment) #starts measurement
        # start the measuring thread
        self.sig_handle_timer.emit(True)
        return 0
    def stop_acqusition(self):
        """ Stops the Wavemeter from measuring and kills the thread that queries the data.
        @return int: error code (0:OK, -1:error)
        """
        # check status just for a sanity check


Please complete the code given below. 
/*
 * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package net.java.sip.communicator.slick.protocol.jabber;
import java.beans.*;
import java.util.*;
import junit.framework.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.protocol.jabberconstants.*;
import net.java.sip.communicator.util.*;
/**
 * Tests Jabber implementations of a Presence Operation Set. Tests in this class
 * verify functionality such as: Changing local (our own) status and
 * corresponding event dispatching; Querying status of contacts, Subscribing
 * for presence notifications upong status changes of specific contacts.
 * <p>
 * Using a custom suite() method, we make sure that apart from standard test
 * methods (those with a <tt>test</tt> prefix) we also execute those that
 * we want run in a specific order like for example - postTestSubscribe() and
 * postTestUnsubscribe().
 * <p>
 * @author Damian Minkov
 * @author Lubomir Marinov
 */
public class TestOperationSetPresence
    extends TestCase
{
    private static final Logger logger =
        Logger.getLogger(TestOperationSetPresence.class);
    private JabberSlickFixture fixture = new JabberSlickFixture();
    private OperationSetPresence operationSetPresence1 = null;
    private final Map<String, PresenceStatus> supportedStatusSet1
        = new HashMap<String, PresenceStatus>();
    private OperationSetPresence operationSetPresence2 = null;
    private final Map<String, PresenceStatus> supportedStatusSet2
        = new HashMap<String, PresenceStatus>();
    private String statusMessageRoot = new String("Our status is now: ");
    private static AuthEventCollector authEventCollector1
        = new AuthEventCollector();
    private static AuthEventCollector authEventCollector2
        = new AuthEventCollector();
    public TestOperationSetPresence(String name)
    {
        super(name);
    }
    @Override
    protected void setUp() throws Exception
    {
        super.setUp();
        fixture.setUp();
        Map<String, OperationSet> supportedOperationSets1 =
            fixture.provider1.getSupportedOperationSets();
        if ( supportedOperationSets1 == null
            || supportedOperationSets1.size() < 1)
            throw new NullPointerException(
                "No OperationSet implementations are supported by "
                +"this implementation. ");
        //get the operation set presence here.
        operationSetPresence1 =
            (OperationSetPresence)supportedOperationSets1.get(
                OperationSetPresence.class.getName());
        //if the op set is null then the implementation doesn't offer a presence
        //operation set which is unacceptable for jabber.
        if (operationSetPresence1 == null)
        {
            throw new NullPointerException(
                "An implementation of the Jabber service must provide an "
                + "implementation of at least the one of the Presence "
                + "Operation Sets");
        }
        // do it once again for the second provider
        Map<String, OperationSet> supportedOperationSets2 =
            fixture.provider2.getSupportedOperationSets();
        if ( supportedOperationSets2 == null
            || supportedOperationSets2.size() < 1)
            throw new NullPointerException(
                "No OperationSet implementations are supported by "
                +"this Jabber implementation. ");
        //get the operation set presence here.
        operationSetPresence2 =
            (OperationSetPresence)supportedOperationSets2.get(
                OperationSetPresence.class.getName());
        //if the op set is null then the implementation doesn't offer a presence
        //operation set which is unacceptable for jabber.
        if (operationSetPresence2 == null)
        {
            throw new NullPointerException(
                "An implementation of the Jabber service must provide an "
                + "implementation of at least the one of the Presence "
                + "Operation Sets");
        }
        /*
         * Retrieve the supported PresenceStatus values because the instances
         * are specific to the ProtocolProviderService implementations.
         */
        // operationSetPresence1
        for (Iterator<PresenceStatus> supportedStatusIt
                        = operationSetPresence1.getSupportedStatusSet();
             supportedStatusIt.hasNext();)
        {
            PresenceStatus supportedStatus = supportedStatusIt.next();
            supportedStatusSet1.put(supportedStatus.getStatusName(),
                supportedStatus);
        }
        // operationSetPresence2
        for (Iterator<PresenceStatus> supportedStatusIt
                        = operationSetPresence2.getSupportedStatusSet();
             supportedStatusIt.hasNext();)
        {
            PresenceStatus supportedStatus = supportedStatusIt.next();
            supportedStatusSet2.put(supportedStatus.getStatusName(),
                supportedStatus);
        }
    }
    @Override
    protected void tearDown() throws Exception
    {
        super.tearDown();
        fixture.tearDown();
    }
    /**
     * Creates a test suite containing all tests of this class followed by
     * test methods that we want executed in a specified order.
     * @return Test
     */
    public static Test suite()
    {
        //return an (almost) empty suite if we're running in offline mode.
        if(JabberSlickFixture.onlineTestingDisabled)
        {
            TestSuite suite = new TestSuite();
            //the only test around here that we could run without net
            //connectivity
            suite.addTest(
                new TestOperationSetPresence(
                        "testSupportedStatusSetForCompleteness"));
            return suite;
        }
        TestSuite suite = new TestSuite();
        // clear the lists before subscribing users
        suite.addTest(new TestOperationSetPresence("clearLists"));
        // first postTestSubscribe. to be sure that contacts are in the
        // list so we can further continue and test presences each other
        suite.addTest(new TestOperationSetPresence("postTestSubscribe"));
//        // add other tests
//        suite.addTestSuite(TestOperationSetPresence.class);
//
        // now test unsubscribe
        suite.addTest(new TestOperationSetPresence("postTestUnsubscribe"));
        return suite;
    }
    /**
     * Verifies that all necessary Jabber test states are supported by the
     * implementation.
     */
    public void testSupportedStatusSetForCompleteness()
    {
        //first create a local list containing the presence status instances
        //supported by the underlying implementation.
        Iterator<PresenceStatus> supportedStatusSetIter =
            operationSetPresence1.getSupportedStatusSet();
        List<String> supportedStatusNames = new LinkedList<String>();
        while (supportedStatusSetIter.hasNext())
        {
            supportedStatusNames.add(supportedStatusSetIter
                .next().getStatusName());
        }
        //create a copy of the MUST status set and remove any matching status
        //that is also present in the supported set.


Please complete the code given below. 
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using LobbyClient;
using PlasmaDownloader;
using PlasmaShared;
using Ratings;
using ZeroKWeb.SpringieInterface;
using ZkData;
using ZkData.UnitSyncLib;
using static System.String;
using Timer = System.Timers.Timer;
 
namespace ZkLobbyServer
{
    public class ServerBattle : Battle
    {
        public const int PollTimeout = 60;
        public const int MapVoteTime = 25;
        public const int NumberOfMapChoices = 4;
        public const int MinimumAutostartPlayers = 6;
        public static int BattleCounter;
        public int QueueCounter = 0;
        public static readonly Dictionary<string, BattleCommand> Commands = new Dictionary<string, BattleCommand>();
        private static object pickPortLock = new object();
        private static string hostingIp;
        public int DiscussionSeconds = 25;
        public readonly List<string> toNotify = new List<string>();
        public Resource HostedMap;
        public Resource HostedMod;
        public Mod HostedModInfo;
        private int hostingPort;
        private int? dbAutohostIndex;
        protected bool isZombie;
        protected bool IsPollsBlocked => IsAutohost && DateTime.UtcNow < BlockPollsUntil;
        private List<KickedPlayer> kickedPlayers = new List<KickedPlayer>();
        public List<BattleDebriefing> Debriefings { get; private set; } = new List<BattleDebriefing>();
        private Timer pollTimer;
        private Timer discussionTimer;
        public ZkLobbyServer server;
        public DedicatedServer spring;
        public string battleInstanceGuid;
        PlayerTeam startGameStatus;
        public int InviteMMPlayers { get; protected set; } = int.MaxValue; //will invite players to MM after each battle if more than X players
        public MapSupportLevel MinimalMapSupportLevel => IsAutohost ? MinimalMapSupportLevelAutohost : (IsPassworded ? MapSupportLevel.None : MapSupportLevel.Supported);
        public CommandPoll ActivePoll { get; private set; }
        public bool IsAutohost { get; private set; }
        public bool IsDefaultGame { get; private set; } = true;
        public bool IsCbalEnabled { get; private set; } = true;
        public override bool TimeQueueEnabled => DynamicConfig.Instance.TimeQueueEnabled && (Mode == AutohostMode.Teams || Mode == AutohostMode.Game1v1 || Mode == AutohostMode.GameFFA);
        public MapSupportLevel MinimalMapSupportLevelAutohost { get; protected set; } = MapSupportLevel.Featured;
        static ServerBattle()
        {
            Commands =
                Assembly.GetAssembly(typeof(BattleCommand))
                    .GetTypes()
                    .Where(x => !x.IsAbstract && x.IsClass && typeof(BattleCommand).IsAssignableFrom(x))
                    .Select(x => x.GetConstructor(new Type[] { }).Invoke(new object[] { }))
                    .Cast<BattleCommand>()
                    .ToDictionary(x => x.Shortcut, x => x);
            hostingIp =
                Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork)?.ToString() ??
                "127.0.0.1";
        }
        public ServerBattle(ZkLobbyServer server, string founder)
        {
            BattleID = Interlocked.Increment(ref BattleCounter);
            FounderName = founder;
            battleInstanceGuid = Guid.NewGuid().ToString();
            this.server = server;
            pollTimer = new Timer(PollTimeout * 1000);
            pollTimer.Enabled = false;
            pollTimer.AutoReset = false;
            pollTimer.Elapsed += pollTimer_Elapsed;
            discussionTimer = new Timer(DiscussionSeconds * 1000);
            discussionTimer.Enabled = false;
            discussionTimer.AutoReset = false;
            discussionTimer.Elapsed += discussionTimer_Elapsed;
            SetupSpring();
            PickHostingPort();
        }
        public void SaveToDb()
        {
            if (!IsAutohost) return;
            using (var db = new ZkDataContext())
            {
                Autohost autohost = null;
                bool insert = false;
                if (dbAutohostIndex.HasValue)
                {
                    autohost = db.Autohosts.Where(x => x.AutohostID == dbAutohostIndex).FirstOrDefault();
                }
                if (autohost == null)
                {
                    insert = true;
                    autohost = new Autohost();
                }
                autohost.MinimumMapSupportLevel = MinimalMapSupportLevelAutohost;
                autohost.AutohostMode = Mode;
                autohost.InviteMMPlayers = InviteMMPlayers;
                autohost.MaxElo = MaxElo;
                autohost.MinElo = MinElo;
                autohost.MaxLevel = MaxLevel;
                autohost.MinLevel = MinLevel;
                autohost.MaxRank = MaxRank;
                autohost.MinRank = MinRank;
                autohost.Title = Title;
                autohost.MaxPlayers = MaxPlayers;
                autohost.CbalEnabled = IsCbalEnabled;
                autohost.MaxEvenPlayers = MaxEvenPlayers;
                autohost.ApplicableRating = ApplicableRating;
                autohost.ModName = HostedMod?.InternalName ?? ModName;
                autohost.MapName = HostedMap?.InternalName ?? MapName;
                if (insert)
                {
                    db.Autohosts.Add(autohost);
                }
                db.SaveChanges();
                dbAutohostIndex = autohost.AutohostID;
            }
        }
        public string GenerateClientScriptPassword(string name)
        {
            return Hash.HashString(battleInstanceGuid + name).ToString();
        }
        public void Dispose()
        {
            spring.UnsubscribeEvents(this);
            if (pollTimer != null) pollTimer.Enabled = false;
            pollTimer?.Dispose();
            pollTimer = null;
            if (discussionTimer != null) discussionTimer.Enabled = false;
            discussionTimer?.Dispose();
            discussionTimer = null;
            spring = null;
            ActivePoll = null;
        }
        public List<string> GetAllUserNames()
        {
            var ret = Users.Select(x => x.Key).ToList();
            if (spring.IsRunning) ret.AddRange(spring.Context.ActualPlayers.Select(x => x.Name));
            return ret.Distinct().ToList();
        }
        public BattleCommand GetCommandByName(string name)
        {
            BattleCommand command;
            if (Commands.TryGetValue(name, out command)) return command.Create();
            return null;
        }
        public ConnectSpring GetConnectSpringStructure(string scriptPassword, bool isSpectator)
        {
            return new ConnectSpring()
            {
                Engine = EngineVersion,
                Ip = hostingIp,
                Port = hostingPort,
                Map = MapName,
                Game = ModName,
                ScriptPassword = scriptPassword,
                Mode = Mode,
                Title = Title,
                IsSpectator = isSpectator,
            };
        }
        public bool IsKicked(string name)
        {
            var kicked = false;
            kickedPlayers.RemoveAll(x => x.TimeOfKicked <= DateTime.UtcNow.AddMinutes(-5));
            if (kickedPlayers.Any(y => y.Name == name)) kicked = true;
            return kicked;
        }
        public async Task KickFromBattle(string name, string reason)
        {
            UserBattleStatus user;
            kickedPlayers.Add(new KickedPlayer() { Name = name });
            if (Users.TryGetValue(name, out user))
            {
                var client = server.ConnectedUsers[name];
                await client.Respond($"You were kicked from battle: {reason}");
                await client.Process(new LeaveBattle() { BattleID = BattleID });
            }
        }
        public virtual async Task CheckCloseBattle()
        {
            if (Users.IsEmpty && !spring.IsRunning)
            {
                if (!IsAutohost)
                    await server.RemoveBattle(this);
                else if (Mode != AutohostMode.None) // custom autohosts would typically be themed around a single map
                    await RunCommandDirectly<CmdMap>(null);
            }
        }
        public void SwitchDefaultGame(bool useDefaultGame)
        {
            IsDefaultGame = useDefaultGame;
        }
        public void SwitchAutohost(bool autohost, string founder)
        {
            if (autohost)
            {
                IsAutohost = true;
                IsDefaultGame = true;
                FounderName = "Autohost #" + BattleID;
                SaveToDb();
            }
            else
            {
                IsAutohost = false;
                FounderName = founder;
                if (dbAutohostIndex.HasValue)
                {
                    using (var db = new ZkDataContext())
                    {
                        db.Autohosts.Remove(db.Autohosts.Where(x => x.AutohostID == dbAutohostIndex).FirstOrDefault());
                        db.SaveChanges();
                    }
                }
            }
        }
        public async Task ProcessBattleSay(Say say)
        {
            if (say.User == GlobalConst.NightwatchName) return; // ignore self
            ConnectedUser user;
            server.ConnectedUsers.TryGetValue(say.User, out user);
            if ((say.Place == SayPlace.Battle) && !say.IsEmote && (user?.User.BanMute != true) && (user?.User.BanSpecChat != true) && say.AllowRelay) spring.SayGame($"<{say.User}>{say.Text}"); // relay to spring
            await CheckSayForCommand(say);
        }
        private async Task<bool> CheckSayForCommand(Say say)
        {
            // check if it's command
            if (!say.IsEmote && (say.Text?.Length > 1) && say.Text.StartsWith("!"))
            {
                var parts = say.Text.Substring(1).Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                return await RunCommandWithPermissionCheck(say, parts[0], parts.Skip(1).FirstOrDefault());
            }
            return false;
        }
        public virtual async Task ProcessPlayerJoin(ConnectedUser user, string joinPassword)
        {
            if (IsPassworded && (Password != joinPassword))
            {
                await user.Respond("Invalid password");
                return;
            }
            if (IsKicked(user.Name))
            {
                await KickFromBattle(user.Name, "Banned for five minutes");
                return;
            }
            if ((user.MyBattle != null) && (user.MyBattle != this)) await user.Process(new LeaveBattle());
            UserBattleStatus ubs;
            if (!Users.TryGetValue(user.Name, out ubs))
            {
                ubs = new UserBattleStatus(user.Name, user.User, GenerateClientScriptPassword(user.Name));
                Users[user.Name] = ubs;
            }
            ValidateBattleStatus(ubs);
            user.MyBattle = this;
            await server.TwoWaySyncUsers(user.Name, Users.Keys); // mutually sync user statuses
            await server.SyncUserToAll(user);
            await RecalcSpectators();
            await
                user.SendCommand(new JoinBattleSuccess()
                {
                    BattleID = BattleID,
                    Players = Users.Values.Select(x => x.ToUpdateBattleStatus()).ToList(),
                    Bots = Bots.Values.Select(x => x.ToUpdateBotStatus()).ToList(),
                    Options = ModOptions
                });
            if (ActivePoll != null) await user.SendCommand(ActivePoll.GetBattlePoll());
            await server.Broadcast(Users.Keys.Where(x => x != user.Name), ubs.ToUpdateBattleStatus()); // send my UBS to others in battle
            if (spring.IsRunning)
            {
                spring.AddUser(ubs.Name, ubs.ScriptPassword, ubs.LobbyUser);
                var started = DateTime.UtcNow.Subtract(spring.IngameStartTime ?? RunningSince ?? DateTime.UtcNow);
                started = new TimeSpan((int)started.TotalHours, started.Minutes, started.Seconds);
                await SayBattle($"THIS GAME IS CURRENTLY IN PROGRESS, PLEASE WAIT UNTIL IT ENDS! Running for {started}", ubs.Name);
                await SayBattle("If you say !notify, I will message you when the current game ends.", ubs.Name);
            }
            try
            {
                var ret = PlayerJoinHandler.AutohostPlayerJoined(GetContext(), ubs.LobbyUser.AccountID);
                if (ret != null)
                {
                    if (!IsNullOrEmpty(ret.PrivateMessage)) await SayBattle(ret.PrivateMessage, ubs.Name);
                    if (!IsNullOrEmpty(ret.PublicMessage)) await SayBattle(ret.PublicMessage);
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                await SayBattle("ServerManage error: " + ex);
            }
        }
        public async Task RecalcSpectators()
        {
            var specCount = Users.Values.Count(x => x.IsSpectator);
            var playerCount = Users.Values.Count(x => !x.IsSpectator);
            if (specCount != SpectatorCount || playerCount != NonSpectatorCount)
            {
                SpectatorCount = specCount;
                NonSpectatorCount = playerCount;
                if (GlobalConst.LobbyServerUpdateSpectatorsInstantly)
                {
                    await server.Broadcast(Users.Keys, new BattleUpdate() { Header = new BattleHeader() { SpectatorCount = specCount, BattleID = BattleID, PlayerCount = NonSpectatorCount } });
                }
            }
        }
        public async Task RegisterVote(Say e, int vote)
        {
            if (ActivePoll != null)
            {
                if (await ActivePoll.Vote(e, vote))
                {
                    StopVote();
                }
            }
            else await Respond(e, "There is no poll going on, start some first");
        }
        public async Task RequestConnectSpring(ConnectedUser conus, string joinPassword)
        {
            UserBattleStatus ubs;
            startGameStatus = spring.LobbyStartContext.Players.FirstOrDefault(x => x.Name == conus.Name);
            
            if (!Users.TryGetValue(conus.Name, out ubs) && !(IsInGame && startGameStatus != null))
                if (IsPassworded && (Password != joinPassword))
                {
                    await conus.Respond("Invalid password");
                    return;
                }
            var pwd = GenerateClientScriptPassword(conus.Name);
            spring.AddUser(conus.Name, pwd, conus.User);
            if (spring.Context.LobbyStartContext.Players.Any(x => x.Name == conus.Name) && conus.MyBattle != this)
            {
                await ProcessPlayerJoin(conus, joinPassword);
            }
            await conus.SendCommand(GetConnectSpringStructure(pwd, startGameStatus?.IsSpectator != false));
        }
        public Task Respond(Say e, string text)
        {
            return SayBattle(text, e?.User);
        }
        public async Task RunCommandDirectly<T>(Say e, string args = null) where T : BattleCommand, new()
        {
            var t = new T();
            await t.Run(this, e, args);
        }
        public async Task<bool> RunCommandWithPermissionCheck(Say e, string com, string arg)
        {
            var cmd = GetCommandByName(com);
            if (cmd == null) return false;
            if (isZombie)
            {
                await Respond(e, "This room is now disabled, please join a new one");
                return false;
            }
            string reason;
            var perm = cmd.GetRunPermissions(this, e.User, out reason);
            if (perm == BattleCommand.RunPermission.Run) await cmd.Run(this, e, arg);
            else if (perm == BattleCommand.RunPermission.Vote)
            {
                if (IsPollsBlocked)
                {
                    await Respond(e, "Please wait for a few seconds before starting a poll.");
                    return false;
                }
                await StartVote(cmd, e, arg);
            }
            else
            {
                await Respond(e, reason);
                return false;
            }
            return true;
        }
        public async Task<bool> RunServerBalance(bool isGameStart, int? allyTeams, bool? clanWise)
        {
            try
            {
                var context = GetContext();
                context.Mode = Mode;
                if (!IsCbalEnabled) clanWise = false;
                var balance = Balancer.BalanceTeams(context, isGameStart, allyTeams, clanWise);
                await ApplyBalanceResults(balance);
                return balance.CanStart;
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                return false;
            }
        }
        public void SayGame(string text)
        {
            if (spring?.IsRunning != true) return;
            foreach (var line in text.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
            {
                spring.SayGame(line);
            }
        }
        public async Task SayBattle(string text, string privateUser = null)
        {
            if (!IsNullOrEmpty(text))
            {
                if ((privateUser == null)) spring.SayGame(text);
                foreach (var line in text.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    await
                        server.GhostSay(
                            new Say()
                            {
                                User = GlobalConst.NightwatchName,
                                Text = line,
                                Place = privateUser != null ? SayPlace.BattlePrivate : SayPlace.Battle,
                                Target = privateUser,
                                IsEmote = true,
                                AllowRelay = false,
                            },
                            BattleID);
                }
            }
        }
        public async Task SetModOptions(Dictionary<string, string> options)
        {
            ModOptions = options;
            await server.Broadcast(Users.Keys, new SetModOptions() { Options = options });
        }
        public void SetApplicableRating(RatingCategory rating)
        {
            ApplicableRating = rating;
            SaveToDb();
        }
        public async Task Spectate(string name)
        {
            ConnectedUser usr;
            if (server.ConnectedUsers.TryGetValue(name, out usr)) await usr.Process(new UpdateUserBattleStatus() { Name = usr.Name, IsSpectator = true });
        }
        public async Task<bool> StartGame()
        {
            var context = GetContext();
            if (TimeQueueEnabled) // spectate beyond max players
            {
                int allowedPlayers = MaxPlayers;
                if (context.Players.Where(x => !x.IsSpectator).Count() <= MaxEvenPlayers)
                {
                    allowedPlayers = context.Players.Where(x => !x.IsSpectator).Count() & ~0x1;
                }
                foreach (var plr in context.Players.Where(x=>!x.IsSpectator).OrderBy(x => x.QueueOrder).Skip(allowedPlayers))
                {
                    plr.IsSpectator = true;
                }
            }
            
            
            if (Mode != AutohostMode.None)
            {
                var balance = IsCbalEnabled ? Balancer.BalanceTeams(context, true, null, null) : Balancer.BalanceTeams(context, true, null, false);
                if (!IsNullOrEmpty(balance.Message)) await SayBattle(balance.Message);
                if (!balance.CanStart) return false;
                context.ApplyBalance(balance);
            }
            var startSetup = StartSetup.GetDedicatedServerStartSetup(context);
            if (!await EnsureEngineIsPresent()) return false;
            if (IsInGame || spring.IsRunning)
            {
                await SayBattle("Game already running");
                return false;
            }
            spring.HostGame(startSetup, hostingIp, hostingPort);
            IsInGame = true;
            RunningSince = DateTime.UtcNow;
            foreach (var us in Users.Values)
                if (us != null)
                {
                    ConnectedUser user;
                    if (server.ConnectedUsers.TryGetValue(us.Name, out user)) await user.SendCommand(GetConnectSpringStructure(us.ScriptPassword, startSetup?.Players.FirstOrDefault(x=>x.Name == us.Name)?.IsSpectator != false));
                }
            await server.Broadcast(server.ConnectedUsers.Values, new BattleUpdate() { Header = GetHeader() });
            // remove all from MM
            foreach (var player in startSetup.Players.Where(x => !x.IsSpectator)) {
                if (await server.MatchMaker.RemoveUser(player.Name, false))
                {
                    await server.UserLogSay($"Removing {player.Name} from MM since their custom battle just started.");
                }
            }
            await server.MatchMaker.UpdateAllPlayerStatuses();
            return true;
        }
        public async Task<bool> StartVote(BattleCommand cmd, Say e, string args, int timeout = PollTimeout, CommandPoll poll = null)
        {
            cmd = cmd.Create();
            string topic = cmd.Arm(this, e, args);
            if (topic == null) return false;
            var unwrappedCmd = cmd;
            if (cmd is CmdPoll)
            {
                var split = args.Split(new[] { ' ' }, 2);
                args = split.Length > 1 ? split[1] : "";
                unwrappedCmd = (cmd as CmdPoll).InternalCommand;
            }
            if (unwrappedCmd is CmdMap && string.IsNullOrEmpty(args)) return await CreateMultiMapPoll();
            Func<string, string> selector = cmd.GetIneligibilityReasonFunc(this);
            if (e != null && selector(e.User) != null) return false;
            var options = new List<PollOption>();
            string url = null;
            string map = null;
            if (unwrappedCmd is CmdMap)
            {
                url = $"{GlobalConst.BaseSiteUrl}/Maps/Detail/{(unwrappedCmd as CmdMap).Map.ResourceID}";
                map = (unwrappedCmd as CmdMap).Map.InternalName;
            }
            var numVoters = Users.Values.Count(x => selector(x.Name) == null);
            var voteMargin = unwrappedCmd.GetPollWinMargin(this, numVoters);
            poll = poll ?? new CommandPoll(this, true, true, unwrappedCmd is CmdMap, map, unwrappedCmd is CmdStart, voteMargin);
            options.Add(new PollOption()
            {
                Name = "Yes",
                URL = url,
                Action = async () =>
                {
                    if (cmd.Access == BattleCommand.AccessType.NotIngame && spring.IsRunning) return;
                    if (cmd.Access == BattleCommand.AccessType.Ingame && !spring.IsRunning) return;
                    await cmd.ExecuteArmed(this, e);
                }
            });
            options.Add(new PollOption()
            {
                Name = "No",
                Action = async () => { }
            });
            if (await StartVote(selector, options, e, topic, poll))
            {
                await RegisterVote(e, 1);
                return true;
            }
            return false;
        }
        public async Task<bool> StartVote(Func<string, string> eligibilitySelector, List<PollOption> options, Say creator, string topic, CommandPoll poll, int timeout = PollTimeout)
        {
            if (ActivePoll != null)
            {
                await Respond(creator, $"Please wait, another poll already in progress: {ActivePoll.Topic}");
                return false;
            }
            await poll.Setup(eligibilitySelector, options, creator, topic);
            ActivePoll = poll;
            pollTimer.Interval = timeout * 1000;
            pollTimer.Enabled = true;
            return true;
        }
        public async void StopVote()
        {
            try
            {
                if (ActivePoll == null) return;
                var oldPoll = ActivePoll;
                if (ActivePoll != null) await ActivePoll.End(false);
                if (pollTimer != null) pollTimer.Enabled = false;
                ActivePoll = null;
                await oldPoll?.PublishResult();
            }
            catch (Exception ex)
            {
                Trace.TraceError("Error stopping vote " + ex);
            }
        }
        public async Task SwitchEngine(string engine)
        {
            EngineVersion = engine;
            ValidateAndFillDetails();
            await
                server.Broadcast(server.ConnectedUsers.Values,
                    new BattleUpdate() { Header = new BattleHeader() { BattleID = BattleID, Engine = EngineVersion } });
        }
        public async Task SwitchGame(string internalName)
        {
            ModName = internalName;
            ValidateAndFillDetails();
            if (ModName != server.Game)
            {
                ModOptions["noelo"] = "1";
                await SayBattle("Ratings are disabled, since this game is not vanilla ZK");
                await server.Broadcast(Users.Keys, new SetModOptions() { Options = ModOptions });
            }
            await
                server.Broadcast(server.ConnectedUsers.Values,
                    new BattleUpdate() { Header = new BattleHeader() { BattleID = BattleID, Game = ModName } });
        }
        public async Task SwitchGameType(AutohostMode type)
        {
            Mode = type;
            MapName = null;
            ValidateAndFillDetails();
            await server.Broadcast(server.ConnectedUsers.Values, new BattleUpdate() { Header = GetHeader() });
            SaveToDb();
            // do a full update - mode can also change map/players
        }
        public async Task SwitchMap(string internalName)
        {
            MapName = internalName;
            ValidateAndFillDetails();
            await
                server.Broadcast(server.ConnectedUsers.Values,
                    new BattleUpdate() { Header = new BattleHeader() { BattleID = BattleID, Map = MapName } });
        }
        public async Task SwitchMaxPlayers(int cnt)
        {
            MaxPlayers = cnt;
            ValidateAndFillDetails();
            await
                server.Broadcast(server.ConnectedUsers.Values,
                    new BattleUpdate() { Header = new BattleHeader() { BattleID = BattleID, MaxPlayers = MaxPlayers } });
            SaveToDb();
        }
        public async Task SwitchMaxEvenPlayers(int cnt)
        {
            MaxEvenPlayers = cnt;
            ValidateAndFillDetails();
            await
                server.Broadcast(server.ConnectedUsers.Values,
                    new BattleUpdate() { Header = new BattleHeader() { BattleID = BattleID, MaxEvenPlayers = MaxEvenPlayers } });
            SaveToDb();
        }
        public async Task SwitchInviteMmPlayers(int players)
        {
            InviteMMPlayers = players;
            SaveToDb();
        }
        public async Task ValidateAllBattleStatuses()
        {
            foreach (var ubs in Users.Values)
            {
                ValidateBattleStatus(ubs);
                await server.Broadcast(Users.Keys, ubs.ToUpdateBattleStatus());
            }
            await RecalcSpectators();
        }
        public async Task SwitchMaxElo(int elo)
        {
            MaxElo = elo;
            SaveToDb();
            await ValidateAllBattleStatuses();
        }
        public async Task SwitchMinElo(int elo)
        {
            MinElo = elo;
            SaveToDb();
            await ValidateAllBattleStatuses();
        }
        public async Task SwitchMaxLevel(int lvl)
        {
            MaxLevel = lvl;
            SaveToDb();
            await ValidateAllBattleStatuses();
        }
        public async Task SwitchMinLevel(int lvl)
        {
            MinLevel = lvl;
            SaveToDb();
            await ValidateAllBattleStatuses();
        }
        public async Task SwitchMaxRank(int rank)
        {
            MaxRank = rank;
            SaveToDb();
            await ValidateAllBattleStatuses();
        }
        public async Task SwitchMinRank(int rank)
        {
            MinRank = rank;
            SaveToDb();
            await ValidateAllBattleStatuses();
        }
        public async Task SwitchMinMapSupportLevel(MapSupportLevel lvl)
        {
            MinimalMapSupportLevelAutohost = lvl;
            SaveToDb();
        }
        public void SwitchCbal(bool cbalEnabled)
        {
            IsCbalEnabled = cbalEnabled;
            SaveToDb();
        }
        public async Task SwitchPassword(string pwd)
        {
            Password = pwd ?? "";
            await server.Broadcast(server.ConnectedUsers.Values, new BattleUpdate() { Header = GetHeader() });
            // do a full update to hide pwd properly
        }
        public async Task SwitchTitle(string title)
        {
            Title = title;
            ValidateAndFillDetails();
            await
                server.Broadcast(server.ConnectedUsers.Values,
                    new BattleUpdate() { Header = new BattleHeader() { BattleID = BattleID, Title = Title } });
            SaveToDb();
        }
        public void BlockPolls(int seconds)
        {
            var target = DateTime.UtcNow.AddSeconds(seconds);
            if (BlockPollsUntil < target) BlockPollsUntil = target;
        }
        public void UpdateWith(Autohost autohost)
        {
            IsAutohost = true;
            MinimalMapSupportLevelAutohost = autohost.MinimumMapSupportLevel;
            Mode = autohost.AutohostMode;
            InviteMMPlayers = autohost.InviteMMPlayers;
            MaxElo = autohost.MaxElo;
            MinElo = autohost.MinElo;
            MaxLevel = autohost.MaxLevel;
            MinLevel = autohost.MinLevel;
            MaxRank = autohost.MaxRank;
            MinRank = autohost.MinRank;
            Title = autohost.Title;
            MaxPlayers = autohost.MaxPlayers;
            IsCbalEnabled = autohost.CbalEnabled;
            dbAutohostIndex = autohost.AutohostID;
            MaxEvenPlayers = autohost.MaxEvenPlayers;
            ApplicableRating = autohost.ApplicableRating;
            FounderName = "Autohost #" + BattleID;
            ValidateAndFillDetails();
            SwitchGame(autohost.ModName);
            SwitchMap(autohost.MapName);
            RunCommandDirectly<CmdMap>(null);
        }
        public override void UpdateWith(BattleHeader h)
        {
            // following variables cannot be overriden in serverbattle
            h.BattleID = BattleID;
            h.Founder = FounderName;
            h.IsRunning = IsInGame;
            h.RunningSince = RunningSince;
            h.SpectatorCount = SpectatorCount;
            h.PlayerCount = NonSpectatorCount;
            h.IsMatchMaker = IsMatchMakerBattle;
            base.UpdateWith(h);
            SwitchGame(h.Game);
            ValidateAndFillDetails();
        }
        public void ValidateAndFillDetails()
        {
            if (IsNullOrEmpty(Title)) Title = $"{FounderName}'s game";
            if (IsNullOrEmpty(EngineVersion) || (Mode != AutohostMode.None)) EngineVersion = server.Engine;
            server.Downloader.GetResource(DownloadType.ENGINE, server.Engine);
            switch (Mode)
            {
                case AutohostMode.Game1v1:
                    MaxPlayers = 2;
                    break;
                case AutohostMode.Planetwars:
                    if (MaxPlayers < 2) MaxPlayers = 16;
                    break;
                case AutohostMode.GameChickens:
                    if (MaxPlayers < 2) MaxPlayers = 10;
                    break;
                case AutohostMode.GameFFA:
                    if (MaxPlayers < 3) MaxPlayers = 16;
                    break;
                case AutohostMode.Teams:
                    if (MaxPlayers < 4) MaxPlayers = 16;
                    break;
                case AutohostMode.None:
                    if (MaxPlayers == 0) MaxPlayers = 16;
                    break;
            }
            if (MaxPlayers > DynamicConfig.Instance.MaximumBattlePlayers && !IsAutohost) MaxPlayers = DynamicConfig.Instance.MaximumBattlePlayers;
            if (MaxEvenPlayers > MaxPlayers) MaxEvenPlayers = MaxPlayers;
            HostedMod = MapPicker.FindResources(ResourceType.Mod, ModName ?? server.Game ?? GlobalConst.DefaultZkTag).FirstOrDefault();
            HostedMap = MapName != null
                ? MapPicker.FindResources(ResourceType.Map, MapName).FirstOrDefault()
                : MapPicker.GetRecommendedMap(GetContext());
            ModName = HostedMod?.InternalName ?? ModName ?? server.Game ?? GlobalConst.DefaultZkTag;
            MapName = HostedMap?.InternalName ?? MapName ?? "Small_Divide-Remake-v04";
            if (HostedMod != null)
                try
                {
                    HostedModInfo = MetaDataCache.ServerGetMod(HostedMod.InternalName);
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning("Error loading mod metadata for {0} : {1}", HostedMod.InternalName, ex);
                }
        }
        public virtual void ValidateBattleStatus(UserBattleStatus ubs)
        {
            if (Mode != AutohostMode.None) ubs.AllyNumber = 0;
            if (!ubs.IsSpectator)
            {
                if (!TimeQueueEnabled && Users.Values.Count(x => !x.IsSpectator) > MaxPlayers)
                {
                    ubs.IsSpectator = true;
                    SayBattle("This battle is full.", ubs.Name);
                }
                if (Users.Values.Count(x => !x.IsSpectator) <= DynamicConfig.Instance.MaximumStatLimitedBattlePlayers || IsAutohost)
                {
                    if (ubs.LobbyUser.EffectiveElo > MaxElo && ubs.LobbyUser.EffectiveMmElo > MaxElo)
                    {
                        ubs.IsSpectator = true;
                        SayBattle("Your rating (" + Math.Min(ubs.LobbyUser.EffectiveElo, ubs.LobbyUser.EffectiveMmElo) + ") is too high. The maximum rating to play in this battle is " + MaxElo + ".", ubs.Name);
                    }
                    if (ubs.LobbyUser.EffectiveElo < MinElo && ubs.LobbyUser.EffectiveMmElo < MinElo)
                    {
                        ubs.IsSpectator = true;
                        SayBattle("Your rating (" + Math.Max(ubs.LobbyUser.EffectiveElo, ubs.LobbyUser.EffectiveMmElo) + ") is too low. The minimum rating to play in this battle is " + MinElo + ".", ubs.Name);
                    }
                    if (ubs.LobbyUser.Level > MaxLevel)
                    {
                        ubs.IsSpectator = true;
                        SayBattle("Your level (" + ubs.LobbyUser.Level + ") is too high. The maximum level to play in this battle is " + MaxLevel + ".", ubs.Name);
                    }
                    if (ubs.LobbyUser.Level < MinLevel)
                    {
                        ubs.IsSpectator = true;
                        SayBattle("Your level (" + ubs.LobbyUser.Level + ") is too low. The minimum level to play in this battle is " + MinLevel + ".", ubs.Name);
                    }
                    if (ubs.LobbyUser.Rank > MaxRank)
                    {
                        ubs.IsSpectator = true;
                        SayBattle("Your Rank (" + Ranks.RankNames[ubs.LobbyUser.Rank] + ") is too high. The maximum Rank to play in this battle is " + Ranks.RankNames[MaxRank] + ".", ubs.Name);
                    }
                    if (ubs.LobbyUser.Rank < MinRank)
                    {
                        ubs.IsSpectator = true;
                        SayBattle("Your Rank (" + Ranks.RankNames[ubs.LobbyUser.Rank] + ") is too low. The minimum Rank to play in this battle is " + Ranks.RankNames[MinRank] + ".", ubs.Name);
                    }
                }
                if (ubs.QueueOrder <= 0) ubs.QueueOrder = ++QueueCounter;
            }
            else
            {
                ubs.QueueOrder = -1;
            }
        }
        protected virtual async Task OnDedicatedExited(SpringBattleContext springBattleContext)
        {
            StopVote();
            IsInGame = false;
            RunningSince = null;
            BlockPollsUntil = DateTime.UtcNow.AddSeconds(DiscussionSeconds);
            bool result = BattleResultHandler.SubmitSpringBattleResult(springBattleContext, server, (debriefing) =>
            {
                Debriefings.Add(debriefing);
                server.Broadcast(springBattleContext.ActualPlayers.Select(x => x.Name), debriefing);
                Trace.TraceInformation("Battle ended: Sent out debriefings for B" + debriefing.ServerBattleID);
            });
            await server.Broadcast(server.ConnectedUsers.Keys, new BattleUpdate() { Header = GetHeader() });
            foreach (var s in toNotify)
                await
                    server.GhostSay(new Say()
                    {
                        User = GlobalConst.NightwatchName,
                        Text = $"** {FounderName} 's {Title} just ended, join me! **",
                        Target = s,
                        IsEmote = true,
                        Place = SayPlace.User,
                        Ring = true,
                        AllowRelay = false
                    });
            toNotify.Clear();
            var playingEligibleUsers = server.MatchMaker.GetEligibleQuickJoinPlayers(Users.Values.Where(x => !x.LobbyUser.IsAway && !x.IsSpectator && x.Name != null).Select(x => server.ConnectedUsers[x.Name]).ToList());
            if (playingEligibleUsers.Count() >= InviteMMPlayers)
            { //Make sure there are enough eligible users for a battle to be likely to happen
                //put all users into MM queue to suggest battles
                var teamsQueues = server.MatchMaker.PossibleQueues.Where(x => x.Mode == AutohostMode.Teams).ToList();
                var availableUsers = Users.Values.Where(x => !x.LobbyUser.IsAway && x.Name != null).Select(x => server.ConnectedUsers[x.Name]).ToList();
                await server.MatchMaker.MassJoin(availableUsers, teamsQueues);
                DiscussionSeconds = MatchMaker.TimerSeconds + 2;
            }
            else
            {
                DiscussionSeconds = 5;
            }
            BlockPollsUntil = DateTime.UtcNow.AddSeconds(DiscussionSeconds);
            if (Mode != AutohostMode.None && (IsAutohost || (!Users.ContainsKey(FounderName) || Users[FounderName].LobbyUser?.IsAway == true) && Mode != AutohostMode.Planetwars && !IsPassworded))
            {
                if (!result)
                {
                    //Game was aborted/exited/invalid, allow manual commands
                    BlockPollsUntil = DateTime.UtcNow;
                }
                else
                {
                    //Initiate discussion time, then map vote, then start vote
                    discussionTimer.Interval = (DiscussionSeconds - 1) * 1000;
                    discussionTimer.Start();
                }
            }
            await CheckCloseBattle();
        }
        private async Task<bool> CreateMultiMapPoll()
        {
            var poll = new CommandPoll(this, false, false, true);
            poll.PollEnded += MapVoteEnded;
            var options = new List<PollOption>();
            List<int> pickedMaps = new List<int>();
            pickedMaps.Add(HostedMap?.ResourceID ?? 0);
            using (var db = new ZkDataContext())
            {
                for (int i = 0; i < NumberOfMapChoices; i++)
                {
                    Resource map = null;
                    if (i < NumberOfMapChoices / 2)
                    {
                        map = MapPicker.GetRecommendedMap(GetContext(), (MinimalMapSupportLevel < MapSupportLevel.Supported) ? MapSupportLevel.Supported : MinimalMapSupportLevel, MapRatings.GetMapRanking(Mode).TakeWhile(x => x.Percentile < 0.2).Select(x => x.Map).Where(x => !pickedMaps.Contains(x.ResourceID)).AsQueryable()); //choose at least 50% popular maps
                    }
                    if (map == null)
                    {
                        map = MapPicker.GetRecommendedMap(GetContext(), (MinimalMapSupportLevel < MapSupportLevel.Featured) ? MapSupportLevel.Supported : MinimalMapSupportLevel, db.Resources.Where(x => !pickedMaps.Contains(x.ResourceID)));
                    }
                    pickedMaps.Add(map.ResourceID);
                    options.Add(new PollOption()
                    {
                        Name = map.InternalName,
                        DisplayName = map.MapNameWithDimensions(),
                        URL = $"{GlobalConst.BaseSiteUrl}/Maps/Detail/{map.ResourceID}",
                        ResourceID = map.ResourceID,
                        Action = async () =>
                        {
                            var cmd = new CmdMap().Create();
                            cmd.Arm(this, null, map.ResourceID.ToString());
                            if (cmd.Access == BattleCommand.AccessType.NotIngame && spring.IsRunning) return;
                            if (cmd.Access == BattleCommand.AccessType.Ingame && !spring.IsRunning) return;


Please complete the code given below. 
namespace OpenDental{
	partial class FormHL7DefEdit {
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing) {
			if(disposing && (components != null)) {
				components.Dispose();
			}
			base.Dispose(disposing);
		}
		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent() {
			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormHL7DefEdit));
			this.label15 = new System.Windows.Forms.Label();
			this.label6 = new System.Windows.Forms.Label();
			this.label5 = new System.Windows.Forms.Label();
			this.label4 = new System.Windows.Forms.Label();
			this.label3 = new System.Windows.Forms.Label();
			this.textNote = new System.Windows.Forms.TextBox();
			this.labelOutAddrPortEx = new System.Windows.Forms.Label();
			this.labelInAddrPortEx = new System.Windows.Forms.Label();
			this.textInternalTypeVersion = new System.Windows.Forms.TextBox();
			this.label13 = new System.Windows.Forms.Label();
			this.textInternalType = new System.Windows.Forms.TextBox();
			this.label14 = new System.Windows.Forms.Label();
			this.checkEnabled = new System.Windows.Forms.CheckBox();
			this.textEscChar = new System.Windows.Forms.TextBox();
			this.label12 = new System.Windows.Forms.Label();
			this.checkInternal = new System.Windows.Forms.CheckBox();
			this.label11 = new System.Windows.Forms.Label();
			this.textSubcompSep = new System.Windows.Forms.TextBox();
			this.label9 = new System.Windows.Forms.Label();
			this.textRepSep = new System.Windows.Forms.TextBox();
			this.label10 = new System.Windows.Forms.Label();
			this.textCompSep = new System.Windows.Forms.TextBox();
			this.label8 = new System.Windows.Forms.Label();
			this.textFieldSep = new System.Windows.Forms.TextBox();
			this.label7 = new System.Windows.Forms.Label();
			this.comboModeTx = new System.Windows.Forms.ComboBox();
			this.textSftpPassword = new System.Windows.Forms.TextBox();
			this.labelSftpPassword = new System.Windows.Forms.Label();
			this.textSftpUsername = new System.Windows.Forms.TextBox();
			this.labelSftpUsername = new System.Windows.Forms.Label();
			this.textOutPathOrAddrPort = new System.Windows.Forms.TextBox();
			this.labelOutPathOrAddrPort = new System.Windows.Forms.Label();
			this.textInPathOrAddrPort = new System.Windows.Forms.TextBox();
			this.labelInPathOrAddrPort = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.label1 = new System.Windows.Forms.Label();
			this.textDescription = new System.Windows.Forms.TextBox();
			this.labelDelete = new System.Windows.Forms.Label();
			this.label16 = new System.Windows.Forms.Label();
			this.label17 = new System.Windows.Forms.Label();
			this.textHL7ServiceName = new System.Windows.Forms.TextBox();
			this.label18 = new System.Windows.Forms.Label();
			this.textHL7Server = new System.Windows.Forms.TextBox();
			this.label19 = new System.Windows.Forms.Label();
			this.groupShowDemographics = new System.Windows.Forms.GroupBox();
			this.label20 = new System.Windows.Forms.Label();
			this.radioChangeAndAdd = new System.Windows.Forms.RadioButton();
			this.radioChange = new System.Windows.Forms.RadioButton();
			this.radioShow = new System.Windows.Forms.RadioButton();
			this.radioHide = new System.Windows.Forms.RadioButton();
			this.checkShowAccount = new System.Windows.Forms.CheckBox();
			this.checkShowAppts = new System.Windows.Forms.CheckBox();
			this.checkQuadAsToothNum = new System.Windows.Forms.CheckBox();
			this.labelLabImageCat = new System.Windows.Forms.Label();
			this.comboLabImageCat = new System.Windows.Forms.ComboBox();
			this.groupDelimeters = new System.Windows.Forms.GroupBox();
			this.groupHL7Comm = new System.Windows.Forms.GroupBox();
			this.butBrowseOut = new OpenDental.UI.Button();
			this.butBrowseIn = new OpenDental.UI.Button();
			this.butAdd = new OpenDental.UI.Button();
			this.butOK = new OpenDental.UI.Button();
			this.butCancel = new OpenDental.UI.Button();
			this.butDelete = new OpenDental.UI.Button();
			this.gridMain = new OpenDental.UI.ODGrid();
			this.groupShowDemographics.SuspendLayout();
			this.groupDelimeters.SuspendLayout();
			this.groupHL7Comm.SuspendLayout();
			this.SuspendLayout();
			// 
			// label15
			// 
			this.label15.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label15.Location = new System.Drawing.Point(166, 93);
			this.label15.Name = "label15";
			this.label15.Size = new System.Drawing.Size(91, 18);
			this.label15.TabIndex = 0;
			this.label15.Text = "Default: \\";
			this.label15.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			// 
			// label6
			// 
			this.label6.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label6.Location = new System.Drawing.Point(166, 73);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(91, 18);
			this.label6.TabIndex = 0;
			this.label6.Text = "Default: &";
			this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			this.label6.UseMnemonic = false;
			// 
			// label5
			// 
			this.label5.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label5.Location = new System.Drawing.Point(166, 53);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(91, 18);
			this.label5.TabIndex = 0;
			this.label5.Text = "Default: ^";
			this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			// 
			// label4
			// 
			this.label4.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label4.Location = new System.Drawing.Point(166, 33);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(91, 18);
			this.label4.TabIndex = 0;
			this.label4.Text = "Default: ~";
			this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			// 
			// label3
			// 
			this.label3.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label3.Location = new System.Drawing.Point(166, 13);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(91, 18);
			this.label3.TabIndex = 0;
			this.label3.Text = "Default: |";
			this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			// 
			// textNote
			// 
			this.textNote.Location = new System.Drawing.Point(443, 184);
			this.textNote.Multiline = true;
			this.textNote.Name = "textNote";
			this.textNote.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
			this.textNote.Size = new System.Drawing.Size(368, 40);
			this.textNote.TabIndex = 62;
			// 
			// labelOutAddrPortEx
			// 
			this.labelOutAddrPortEx.Location = new System.Drawing.Point(336, 39);
			this.labelOutAddrPortEx.Name = "labelOutAddrPortEx";
			this.labelOutAddrPortEx.Size = new System.Drawing.Size(182, 18);
			this.labelOutAddrPortEx.TabIndex = 0;
			this.labelOutAddrPortEx.Text = "Ex: 192.168.0.23:5846";
			this.labelOutAddrPortEx.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			this.labelOutAddrPortEx.Visible = false;
			// 
			// labelInAddrPortEx
			// 
			this.labelInAddrPortEx.Location = new System.Drawing.Point(336, 17);
			this.labelInAddrPortEx.Name = "labelInAddrPortEx";
			this.labelInAddrPortEx.Size = new System.Drawing.Size(182, 18);
			this.labelInAddrPortEx.TabIndex = 0;
			this.labelInAddrPortEx.Text = "Ex: server.address.com:12345";
			this.labelInAddrPortEx.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			this.labelInAddrPortEx.Visible = false;
			// 
			// textInternalTypeVersion
			// 
			this.textInternalTypeVersion.Location = new System.Drawing.Point(155, 112);
			this.textInternalTypeVersion.Name = "textInternalTypeVersion";
			this.textInternalTypeVersion.ReadOnly = true;
			this.textInternalTypeVersion.Size = new System.Drawing.Size(125, 20);
			this.textInternalTypeVersion.TabIndex = 44;
			// 
			// label13
			// 
			this.label13.Location = new System.Drawing.Point(6, 113);
			this.label13.Name = "label13";
			this.label13.Size = new System.Drawing.Size(148, 18);
			this.label13.TabIndex = 0;
			this.label13.Text = "Internal Type Version";
			this.label13.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// textInternalType
			// 
			this.textInternalType.Location = new System.Drawing.Point(155, 92);
			this.textInternalType.Name = "textInternalType";
			this.textInternalType.ReadOnly = true;
			this.textInternalType.Size = new System.Drawing.Size(125, 20);
			this.textInternalType.TabIndex = 43;
			// 
			// label14
			// 
			this.label14.Location = new System.Drawing.Point(6, 93);
			this.label14.Name = "label14";
			this.label14.Size = new System.Drawing.Size(148, 18);
			this.label14.TabIndex = 0;
			this.label14.Text = "Internal Type";
			this.label14.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// checkEnabled
			// 
			this.checkEnabled.Checked = true;
			this.checkEnabled.CheckState = System.Windows.Forms.CheckState.Checked;
			this.checkEnabled.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.checkEnabled.Location = new System.Drawing.Point(6, 30);
			this.checkEnabled.Name = "checkEnabled";
			this.checkEnabled.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
			this.checkEnabled.Size = new System.Drawing.Size(162, 18);
			this.checkEnabled.TabIndex = 40;
			this.checkEnabled.Text = "Enabled";
			this.checkEnabled.CheckedChanged += new System.EventHandler(this.checkEnabled_CheckedChanged);
			this.checkEnabled.Click += new System.EventHandler(this.checkEnabled_Click);
			// 
			// textEscChar
			// 
			this.textEscChar.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.textEscChar.Location = new System.Drawing.Point(138, 92);
			this.textEscChar.Name = "textEscChar";
			this.textEscChar.Size = new System.Drawing.Size(27, 20);
			this.textEscChar.TabIndex = 49;
			// 
			// label12
			// 
			this.label12.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label12.Location = new System.Drawing.Point(6, 93);
			this.label12.Name = "label12";
			this.label12.Size = new System.Drawing.Size(131, 18);
			this.label12.TabIndex = 0;
			this.label12.Text = "Escape";
			this.label12.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// checkInternal
			// 
			this.checkInternal.Enabled = false;
			this.checkInternal.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.checkInternal.Location = new System.Drawing.Point(6, 12);
			this.checkInternal.Name = "checkInternal";
			this.checkInternal.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
			this.checkInternal.Size = new System.Drawing.Size(162, 18);
			this.checkInternal.TabIndex = 31;
			this.checkInternal.TabStop = false;
			this.checkInternal.Text = "Internal";
			// 
			// label11
			// 
			this.label11.Location = new System.Drawing.Point(292, 185);
			this.label11.Name = "label11";
			this.label11.Size = new System.Drawing.Size(150, 18);
			this.label11.TabIndex = 0;
			this.label11.Text = "Note";
			this.label11.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// textSubcompSep
			// 
			this.textSubcompSep.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.textSubcompSep.Location = new System.Drawing.Point(138, 72);
			this.textSubcompSep.Name = "textSubcompSep";
			this.textSubcompSep.Size = new System.Drawing.Size(27, 20);
			this.textSubcompSep.TabIndex = 48;
			// 
			// label9
			// 
			this.label9.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label9.Location = new System.Drawing.Point(6, 73);
			this.label9.Name = "label9";
			this.label9.Size = new System.Drawing.Size(131, 18);
			this.label9.TabIndex = 0;
			this.label9.Text = "Subcomponent";
			this.label9.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// textRepSep
			// 
			this.textRepSep.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.textRepSep.Location = new System.Drawing.Point(138, 32);
			this.textRepSep.Name = "textRepSep";
			this.textRepSep.Size = new System.Drawing.Size(27, 20);
			this.textRepSep.TabIndex = 46;
			// 
			// label10
			// 
			this.label10.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label10.Location = new System.Drawing.Point(6, 33);
			this.label10.Name = "label10";
			this.label10.Size = new System.Drawing.Size(131, 18);
			this.label10.TabIndex = 0;
			this.label10.Text = "Repetition";
			this.label10.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// textCompSep
			// 
			this.textCompSep.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.textCompSep.Location = new System.Drawing.Point(138, 52);
			this.textCompSep.Name = "textCompSep";
			this.textCompSep.Size = new System.Drawing.Size(27, 20);
			this.textCompSep.TabIndex = 47;
			// 
			// label8
			// 
			this.label8.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label8.Location = new System.Drawing.Point(6, 53);
			this.label8.Name = "label8";
			this.label8.Size = new System.Drawing.Size(131, 18);
			this.label8.TabIndex = 0;
			this.label8.Text = "Component";
			this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// textFieldSep
			// 
			this.textFieldSep.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.textFieldSep.Location = new System.Drawing.Point(138, 12);
			this.textFieldSep.Name = "textFieldSep";
			this.textFieldSep.Size = new System.Drawing.Size(27, 20);
			this.textFieldSep.TabIndex = 45;
			// 
			// label7
			// 
			this.label7.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.label7.Location = new System.Drawing.Point(6, 13);
			this.label7.Name = "label7";
			this.label7.Size = new System.Drawing.Size(131, 18);
			this.label7.TabIndex = 0;
			this.label7.Text = "Field";
			this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// comboModeTx
			// 
			this.comboModeTx.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
			this.comboModeTx.Location = new System.Drawing.Point(155, 71);
			this.comboModeTx.MaxDropDownItems = 100;
			this.comboModeTx.Name = "comboModeTx";
			this.comboModeTx.Size = new System.Drawing.Size(125, 21);
			this.comboModeTx.TabIndex = 42;
			this.comboModeTx.SelectedIndexChanged += new System.EventHandler(this.comboModeTx_SelectedIndexChanged);
			// 
			// textSftpPassword
			// 
			this.textSftpPassword.Location = new System.Drawing.Point(157, 78);
			this.textSftpPassword.Name = "textSftpPassword";
			this.textSftpPassword.PasswordChar = '*';
			this.textSftpPassword.Size = new System.Drawing.Size(125, 20);
			this.textSftpPassword.TabIndex = 58;
			// 
			// labelSftpPassword
			// 
			this.labelSftpPassword.Location = new System.Drawing.Point(6, 79);
			this.labelSftpPassword.Name = "labelSftpPassword";
			this.labelSftpPassword.Size = new System.Drawing.Size(150, 18);
			this.labelSftpPassword.TabIndex = 0;
			this.labelSftpPassword.Text = "Sftp Password";
			this.labelSftpPassword.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// textSftpUsername
			// 
			this.textSftpUsername.Location = new System.Drawing.Point(157, 58);
			this.textSftpUsername.Name = "textSftpUsername";
			this.textSftpUsername.Size = new System.Drawing.Size(125, 20);
			this.textSftpUsername.TabIndex = 57;
			// 
			// labelSftpUsername
			// 
			this.labelSftpUsername.Location = new System.Drawing.Point(6, 59);
			this.labelSftpUsername.Name = "labelSftpUsername";
			this.labelSftpUsername.Size = new System.Drawing.Size(150, 18);
			this.labelSftpUsername.TabIndex = 0;
			this.labelSftpUsername.Text = "Sftp Username";
			this.labelSftpUsername.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// textOutPathOrAddrPort
			// 
			this.textOutPathOrAddrPort.Location = new System.Drawing.Point(157, 38);
			this.textOutPathOrAddrPort.Name = "textOutPathOrAddrPort";
			this.textOutPathOrAddrPort.Size = new System.Drawing.Size(177, 20);
			this.textOutPathOrAddrPort.TabIndex = 55;
			// 
			// labelOutPathOrAddrPort
			// 
			this.labelOutPathOrAddrPort.Location = new System.Drawing.Point(6, 39);
			this.labelOutPathOrAddrPort.Name = "labelOutPathOrAddrPort";
			this.labelOutPathOrAddrPort.Size = new System.Drawing.Size(150, 18);
			this.labelOutPathOrAddrPort.TabIndex = 0;
			this.labelOutPathOrAddrPort.Text = "Outgoing Folder";
			this.labelOutPathOrAddrPort.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// textInPathOrAddrPort
			// 
			this.textInPathOrAddrPort.Location = new System.Drawing.Point(157, 16);
			this.textInPathOrAddrPort.Name = "textInPathOrAddrPort";
			this.textInPathOrAddrPort.Size = new System.Drawing.Size(177, 20);
			this.textInPathOrAddrPort.TabIndex = 53;
			// 
			// labelInPathOrAddrPort
			// 
			this.labelInPathOrAddrPort.Location = new System.Drawing.Point(6, 17);
			this.labelInPathOrAddrPort.Name = "labelInPathOrAddrPort";
			this.labelInPathOrAddrPort.Size = new System.Drawing.Size(150, 18);
			this.labelInPathOrAddrPort.TabIndex = 0;
			this.labelInPathOrAddrPort.Text = "Incoming Folder";
			this.labelInPathOrAddrPort.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label2
			// 
			this.label2.Location = new System.Drawing.Point(6, 72);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(148, 18);
			this.label2.TabIndex = 0;
			this.label2.Text = "ModeTx";
			this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label1
			// 


Please complete the code given below. 
//
// System.Web.Compilation.AspComponentFoundry
//
// Authors:
//	Gonzalo Paniagua Javier (gonzalo@ximian.com)
//
// (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
using System.Web.Util;
namespace System.Web.Compilation
{
	class AspComponentFoundry
	{
		Hashtable foundries;
		Dictionary <string, AspComponent> components;
		Dictionary <string, AspComponent> Components {
			get {
				if (components == null)
					components = new Dictionary <string, AspComponent> (StringComparer.OrdinalIgnoreCase);
				return components;
			}
		}
		
		public AspComponentFoundry ()
		{
			foundries = new Hashtable (StringComparer.InvariantCultureIgnoreCase);
			Assembly sw = typeof (AspComponentFoundry).Assembly;
			RegisterFoundry ("asp", sw, "System.Web.UI.WebControls");
			RegisterFoundry ("", "object", typeof (System.Web.UI.ObjectTag));
			RegisterConfigControls ();
		}
		public AspComponent GetComponent (string tagName)
		{
			if (tagName == null || tagName.Length == 0)
				return null;
			
			if (components != null) {
				AspComponent ret;
				if (components.TryGetValue (tagName, out ret))
					return ret;
			}
			string foundryName, tag;
			int colon = tagName.IndexOf (':');
			if (colon > -1) {
				if (colon == 0)
					throw new Exception ("Empty TagPrefix is not valid.");
				if (colon + 1 == tagName.Length)
					return null;
				foundryName = tagName.Substring (0, colon);
				tag = tagName.Substring (colon + 1);
			} else {
				foundryName = String.Empty;
				tag = tagName;
			}
			
			object o = foundries [foundryName];			
			if (o == null)
				return null;
			Foundry foundry = o as Foundry;
			if (foundry != null)
				return CreateComponent (foundry, tagName, foundryName, tag);
			
			ArrayList af = o as ArrayList;
			if (af == null)
				return null;
			AspComponent component = null;
			Exception e = null;
			foreach (Foundry f in af) {
				try {
					component = CreateComponent (f, tagName, foundryName, tag);
					if (component != null)
						return component;
				} catch (Exception ex) {
					e = ex;
				}
			}
			if (e != null)
				throw e;
			
			return null;
		}
		AspComponent CreateComponent (Foundry foundry, string tagName, string prefix, string tag)
		{
			string source, ns;
			Type type;
			type = foundry.GetType (tag, out source, out ns);
			if (type == null)
				return null;
			
			AspComponent ret = new AspComponent (type, ns, prefix, source, foundry.FromConfig);
			Dictionary <string, AspComponent> components = Components;
			components.Add (tagName, ret);
			return ret;
		}
		
		public void RegisterFoundry (string foundryName, Assembly assembly, string nameSpace)
		{
			RegisterFoundry (foundryName, assembly, nameSpace, false);
		}
		
		public void RegisterFoundry (string foundryName,
					     Assembly assembly,
					     string nameSpace,
					     bool fromConfig)
		{
			AssemblyFoundry foundry = new AssemblyFoundry (assembly, nameSpace);
			foundry.FromConfig = fromConfig;
			InternalRegister (foundryName, foundry, fromConfig);
		}
		public void RegisterFoundry (string foundryName, string tagName, Type type)
		{
			RegisterFoundry (foundryName, tagName, type, false);
		}
		
		public void RegisterFoundry (string foundryName,
					     string tagName,
					     Type type,
					     bool fromConfig)
		{
			TagNameFoundry foundry = new TagNameFoundry (tagName, type);
			foundry.FromConfig = fromConfig;
			InternalRegister (foundryName, foundry, fromConfig);
		}
		public void RegisterFoundry (string foundryName, string tagName, string source)
		{
			RegisterFoundry (foundryName, tagName, source, false);
		}
		
		public void RegisterFoundry (string foundryName,
					     string tagName,
					     string source,
					     bool fromConfig)
		{
			TagNameFoundry foundry = new TagNameFoundry (tagName, source);
			foundry.FromConfig = fromConfig;
			InternalRegister (foundryName, foundry, fromConfig);
		}
		public void RegisterAssemblyFoundry (string foundryName,
						     string assemblyName,
						     string nameSpace,
						     bool fromConfig)
		{
			AssemblyFoundry foundry = new AssemblyFoundry (assemblyName, nameSpace);
			foundry.FromConfig = fromConfig;
			InternalRegister (foundryName, foundry, fromConfig);
		}		
		void RegisterConfigControls ()
		{
			PagesSection pages = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
			if (pages == null)
				return;
			TagPrefixCollection controls = pages.Controls;
			if (controls == null || controls.Count == 0)
				return;
			
			IList appCode = BuildManager.CodeAssemblies;
			bool haveCodeAssemblies = appCode != null && appCode.Count > 0;
			Assembly asm;
			foreach (TagPrefixInfo tpi in controls) {
				if (!String.IsNullOrEmpty (tpi.TagName))
					RegisterFoundry (tpi.TagPrefix, tpi.TagName, tpi.Source, true);
				else if (String.IsNullOrEmpty (tpi.Assembly)) {
					if (haveCodeAssemblies) {
						foreach (object o in appCode) {
							asm = o as Assembly;
							if (asm == null)
								continue;
							RegisterFoundry (tpi.TagPrefix, asm, tpi.Namespace, true);
						}
					}
				} else if (!String.IsNullOrEmpty (tpi.Namespace))
					RegisterAssemblyFoundry (tpi.TagPrefix,
								 tpi.Assembly,
								 tpi.Namespace,
								 true);
			}
		}
		
		void InternalRegister (string foundryName, Foundry foundry, bool fromConfig)
		{
			object f = foundries [foundryName];
			Foundry newFoundry = null;
			
			if (f is CompoundFoundry) {
				((CompoundFoundry) f).Add (foundry);
				return;
			} else if (f == null || f is ArrayList || (f is AssemblyFoundry && foundry is AssemblyFoundry)) {
				newFoundry = foundry;
			} else if (f != null) {
				CompoundFoundry compound = new CompoundFoundry (foundryName);
				compound.Add ((Foundry) f);
				compound.Add (foundry);
				newFoundry = foundry;
				newFoundry.FromConfig = fromConfig;
			}
			if (newFoundry == null)
				return;
			if (f == null) {
				foundries [foundryName] = newFoundry;
				return;
			}
			ArrayList af = f as ArrayList;
			if (af == null) {
				af = new ArrayList (2);
				af.Add (f);
				foundries [foundryName] = af;
			}
			if (newFoundry is AssemblyFoundry) {
				object o;
				for (int i = 0; i < af.Count; i++) {
					o = af [i];
					if (o is AssemblyFoundry) {
						af.Insert (i, newFoundry);
						return;
					}
				}
				af.Add (newFoundry);
			} else
				af.Insert (0, newFoundry);
		}
		public bool LookupFoundry (string foundryName)
		{
			return foundries.Contains (foundryName);
		}
		abstract class Foundry
		{
			bool _fromConfig;
			public bool FromConfig {
				get { return _fromConfig; }
				set { _fromConfig = value; }
			}
			
			public abstract Type GetType (string componentName, out string source, out string ns);
		}
		
		class TagNameFoundry : Foundry
		{
			string tagName;
			Type type;
			string source;
			public bool FromWebConfig {
				get { return source != null; }
			}
			
			public TagNameFoundry (string tagName, string source)
			{
				this.tagName = tagName;
				this.source = source;
			}
			
			public TagNameFoundry (string tagName, Type type)
			{
				this.tagName = tagName;
				this.type = type;
			}
			public override Type GetType (string componentName, out string source, out string ns)
			{
				source = null;
				ns = null;
				if (0 != String.Compare (componentName, tagName, true, Helpers.InvariantCulture))
					return null;
				source = this.source;
				return LoadType ();
			}
			Type LoadType ()
			{
				if (type != null)
					return type;
				HttpContext context = HttpContext.Current;
				string vpath;
				string realpath;
				
				if (VirtualPathUtility.IsAppRelative (source)) {
					vpath = source;
					realpath = context.Request.MapPath (source);
				} else {
					vpath = VirtualPathUtility.ToAppRelative (source);
					realpath = source;
				}
				
				if ((type = CachingCompiler.GetTypeFromCache (realpath)) != null)
					return type;				
				type = BuildManager.GetCompiledType (vpath);
				if (type != null) {
					AspGenerator.AddTypeToCache (null, realpath, type);
					BuildManager.AddToReferencedAssemblies (type.Assembly);
				}
				return type;
			}
			
			public string TagName {
				get { return tagName; }
			}
		}
		class AssemblyFoundry : Foundry
		{
			string nameSpace;
			Assembly assembly;
			string assemblyName;
			Dictionary <string, Assembly> assemblyCache;
			
			public AssemblyFoundry (Assembly assembly, string nameSpace)
			{
				this.assembly = assembly;
				this.nameSpace = nameSpace;
				if (assembly != null)
					this.assemblyName = assembly.FullName;
				else
					this.assemblyName = null;
			}
			public AssemblyFoundry (string assemblyName, string nameSpace)
			{
				this.assembly = null;
				this.nameSpace = nameSpace;
				this.assemblyName = assemblyName;
			}
			
			public override Type GetType (string componentName, out string source, out string ns)
			{
				source = null;
				ns = nameSpace;
				if (assembly == null && assemblyName != null)
					assembly = GetAssemblyByName (assemblyName, true);
				string typeName = String.Concat (nameSpace, ".", componentName);
				if (assembly != null)
					return assembly.GetType (typeName, false, true);
				IList tla = BuildManager.TopLevelAssemblies;
				if (tla != null && tla.Count > 0) {
					Type ret = null;
					foreach (Assembly asm in tla) {
						if (asm == null)
							continue;
						ret = asm.GetType (typeName, false, true);
						if (ret != null)
							return ret;
					}
				}
				return null;
			}
			Assembly GetAssemblyByName (string name, bool throwOnMissing)
			{
				if (assemblyCache == null)
					assemblyCache = new Dictionary <string, Assembly> ();
				
				if (assemblyCache.ContainsKey (name))
					return assemblyCache [name];
				
				Assembly assembly = null;
				Exception error = null;
				if (name.IndexOf (',') != -1) {
					try {
						assembly = Assembly.Load (name);
					} catch (Exception e) { error = e; }
				}


Please complete the code given below. 
#!/usr/bin/python
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
#
ANSIBLE_METADATA = {'metadata_version': '1.1',
                    'status': ['preview'],
                    'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ce_link_status
version_added: "2.4"
short_description: Get interface link status on HUAWEI CloudEngine switches.
description:
    - Get interface link status on HUAWEI CloudEngine switches.
author:
    - Zhijin Zhou (@QijunPan)
notes:
    - Current physical state shows an interface's physical status.
    - Current link state shows an interface's link layer protocol status.
    - Current IPv4 state shows an interface's IPv4 protocol status.
    - Current IPv6 state shows an interface's  IPv6 protocol status.
    - Inbound octets(bytes) shows the number of bytes that an interface received.
    - Inbound unicast(pkts) shows the number of unicast packets that an interface received.
    - Inbound multicast(pkts) shows the number of multicast packets that an interface received.
    - Inbound broadcast(pkts) shows  the number of broadcast packets that an interface received.
    - Inbound error(pkts) shows the number of error packets that an interface received.
    - Inbound drop(pkts) shows the total number of packets that were sent to the interface but dropped by an interface.
    - Inbound rate(byte/sec) shows the rate at which an interface receives bytes within an interval.
    - Inbound rate(pkts/sec) shows the rate at which an interface receives packets within an interval.
    - Outbound octets(bytes) shows the number of the bytes that an interface sent.
    - Outbound unicast(pkts) shows  the number of unicast packets that an interface sent.
    - Outbound multicast(pkts) shows the number of multicast packets that an interface sent.
    - Outbound broadcast(pkts) shows the number of broadcast packets that an interface sent.
    - Outbound error(pkts) shows the total number of packets that an interface sent but dropped by the remote interface.
    - Outbound drop(pkts) shows the number of dropped packets that an interface sent.
    - Outbound rate(byte/sec) shows the rate at which an interface sends bytes within an interval.
    - Outbound rate(pkts/sec) shows the rate at which an interface sends packets within an interval.
    - Speed shows the rate for an Ethernet interface.
options:
    interface:
        description:
            - For the interface parameter, you can enter C(all) to display information about all interface,
              an interface type such as C(40GE) to display information about interfaces of the specified type,
              or full name of an interface such as C(40GE1/0/22) or C(vlanif10)
              to display information about the specific interface.
        required: true
'''
EXAMPLES = '''
- name: Link status test
  hosts: cloudengine
  connection: local
  gather_facts: no
  vars:
    cli:
      host: "{{ inventory_hostname }}"
      port: "{{ ansible_ssh_port }}"
      username: "{{ username }}"
      password: "{{ password }}"
      transport: cli
  tasks:
  - name: Get specified interface link status information
    ce_link_status:
      interface: 40GE1/0/1
      provider: "{{ cli }}"
  - name: Get specified interface type link status information
    ce_link_status:
      interface: 40GE
      provider: "{{ cli }}"
  - name: Get all interface link status information
    ce_link_status:
      interface: all
      provider: "{{ cli }}"
'''
RETURN = '''
result:
    description: Interface link status information
    returned: always
    type: dict
    sample: {
                "40ge2/0/8": {
                    "Current IPv4 state": "down",
                    "Current IPv6 state": "down",
                    "Current link state": "up",
                    "Current physical state": "up",
                    "Inbound broadcast(pkts)": "0",
                    "Inbound drop(pkts)": "0",
                    "Inbound error(pkts)": "0",
                    "Inbound multicast(pkts)": "20151",
                    "Inbound octets(bytes)": "7314813",
                    "Inbound rate(byte/sec)": "11",
                    "Inbound rate(pkts/sec)": "0",
                    "Inbound unicast(pkts)": "0",
                    "Outbound broadcast(pkts)": "1",
                    "Outbound drop(pkts)": "0",
                    "Outbound error(pkts)": "0",
                    "Outbound multicast(pkts)": "20152",
                    "Outbound octets(bytes)": "7235021",
                    "Outbound rate(byte/sec)": "11",
                    "Outbound rate(pkts/sec)": "0",
                    "Outbound unicast(pkts)": "0",
                    "Speed": "40GE"
                }
            }
'''
from xml.etree import ElementTree
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.cloudengine.ce import ce_argument_spec, get_nc_config
CE_NC_GET_PORT_SPEED = """
<filter type="subtree">
  <devm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
    <ports>
      <port>
        <position>%s</position>
        <ethernetPort>
          <speed></speed>
        </ethernetPort>
      </port>
    </ports>
  </devm>
</filter>
"""
CE_NC_GET_INT_STATISTICS = """
<filter type="subtree">
  <ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
    <interfaces>
      <interface>
        <ifName>%s</ifName>
        <ifDynamicInfo>
          <ifPhyStatus></ifPhyStatus>
          <ifLinkStatus></ifLinkStatus>
          <ifV4State></ifV4State>
          <ifV6State></ifV6State>
        </ifDynamicInfo>
        <ifStatistics>
          <receiveByte></receiveByte>
          <sendByte></sendByte>
          <rcvUniPacket></rcvUniPacket>
          <rcvMutiPacket></rcvMutiPacket>
          <rcvBroadPacket></rcvBroadPacket>
          <sendUniPacket></sendUniPacket>
          <sendMutiPacket></sendMutiPacket>
          <sendBroadPacket></sendBroadPacket>
          <rcvErrorPacket></rcvErrorPacket>
          <rcvDropPacket></rcvDropPacket>
          <sendErrorPacket></sendErrorPacket>
          <sendDropPacket></sendDropPacket>
        </ifStatistics>
        <ifClearedStat>
          <inByteRate></inByteRate>
          <inPacketRate></inPacketRate>
          <outByteRate></outByteRate>
          <outPacketRate></outPacketRate>
        </ifClearedStat>
      </interface>
    </interfaces>
  </ifm>
</filter>
"""
INTERFACE_ALL = 1
INTERFACE_TYPE = 2
INTERFACE_FULL_NAME = 3
def get_interface_type(interface):
    """Gets the type of interface, such as 10GE, ETH-TRUNK, VLANIF..."""
    if interface is None:
        return None
    iftype = None
    if interface.upper().startswith('GE'):
        iftype = 'ge'
    elif interface.upper().startswith('10GE'):
        iftype = '10ge'
    elif interface.upper().startswith('25GE'):
        iftype = '25ge'
    elif interface.upper().startswith('4X10GE'):
        iftype = '4x10ge'
    elif interface.upper().startswith('40GE'):
        iftype = '40ge'
    elif interface.upper().startswith('100GE'):
        iftype = '100ge'
    elif interface.upper().startswith('VLANIF'):
        iftype = 'vlanif'
    elif interface.upper().startswith('LOOPBACK'):
        iftype = 'loopback'
    elif interface.upper().startswith('METH'):
        iftype = 'meth'
    elif interface.upper().startswith('ETH-TRUNK'):
        iftype = 'eth-trunk'
    elif interface.upper().startswith('VBDIF'):
        iftype = 'vbdif'
    elif interface.upper().startswith('NVE'):
        iftype = 'nve'
    elif interface.upper().startswith('TUNNEL'):
        iftype = 'tunnel'
    elif interface.upper().startswith('ETHERNET'):
        iftype = 'ethernet'
    elif interface.upper().startswith('FCOE-PORT'):
        iftype = 'fcoe-port'
    elif interface.upper().startswith('FABRIC-PORT'):
        iftype = 'fabric-port'
    elif interface.upper().startswith('STACK-PORT'):
        iftype = 'stack-Port'
    elif interface.upper().startswith('NULL'):
        iftype = 'null'
    else:
        return None
    return iftype.lower()
def is_ethernet_port(interface):
    """Judge whether it is ethernet port"""
    ethernet_port = ['ge', '10ge', '25ge', '4x10ge', '40ge', '100ge', 'meth']
    if_type = get_interface_type(interface)
    if if_type in ethernet_port:
        return True
    return False
class LinkStatus(object):
    """Get interface link status information"""
    def __init__(self, argument_spec):
        self.spec = argument_spec
        self.module = None
        self.init_module()
        # interface name
        self.interface = self.module.params['interface']
        self.interface = self.interface.replace(' ', '').lower()
        self.param_type = None
        self.if_type = None
        # state
        self.results = dict()
        self.result = dict()
    def check_params(self):
        """Check all input params"""
        if not self.interface:
            self.module.fail_json(msg='Error: Interface name cannot be empty.')
        if self.interface and self.interface != 'all':
            if not self.if_type:
                self.module.fail_json(
                    msg='Error: Interface name of %s is error.' % self.interface)
    def init_module(self):
        """Init module object"""
        self.module = AnsibleModule(
            argument_spec=self.spec, supports_check_mode=True)
    def show_result(self):
        """Show result"""
        self.results['result'] = self.result
        self.module.exit_json(**self.results)
    def get_intf_dynamic_info(self, dyn_info, intf_name):
        """Get interface dynamic information"""
        if not intf_name:
            return
        if dyn_info:
            for eles in dyn_info:
                if eles.tag in ["ifPhyStatus", "ifV4State", "ifV6State", "ifLinkStatus"]:
                    if eles.tag == "ifPhyStatus":
                        self.result[intf_name][
                            'Current physical state'] = eles.text
                    elif eles.tag == "ifLinkStatus":
                        self.result[intf_name][
                            'Current link state'] = eles.text
                    elif eles.tag == "ifV4State":
                        self.result[intf_name][
                            'Current IPv4 state'] = eles.text
                    elif eles.tag == "ifV6State":
                        self.result[intf_name][
                            'Current IPv6 state'] = eles.text
    def get_intf_statistics_info(self, stat_info, intf_name):
        """Get interface statistics information"""
        if not intf_name:
            return
        if_type = get_interface_type(intf_name)
        if if_type == 'fcoe-port' or if_type == 'nve' or if_type == 'tunnel' or \
                if_type == 'vbdif' or if_type == 'vlanif':
            return
        if stat_info:
            for eles in stat_info:
                if eles.tag in ["receiveByte", "sendByte", "rcvUniPacket", "rcvMutiPacket", "rcvBroadPacket",
                                "sendUniPacket", "sendMutiPacket", "sendBroadPacket", "rcvErrorPacket",
                                "rcvDropPacket", "sendErrorPacket", "sendDropPacket"]:
                    if eles.tag == "receiveByte":
                        self.result[intf_name][
                            'Inbound octets(bytes)'] = eles.text
                    elif eles.tag == "rcvUniPacket":
                        self.result[intf_name][
                            'Inbound unicast(pkts)'] = eles.text
                    elif eles.tag == "rcvMutiPacket":
                        self.result[intf_name][
                            'Inbound multicast(pkts)'] = eles.text
                    elif eles.tag == "rcvBroadPacket":
                        self.result[intf_name][
                            'Inbound broadcast(pkts)'] = eles.text
                    elif eles.tag == "rcvErrorPacket":
                        self.result[intf_name][
                            'Inbound error(pkts)'] = eles.text
                    elif eles.tag == "rcvDropPacket":
                        self.result[intf_name][
                            'Inbound drop(pkts)'] = eles.text
                    elif eles.tag == "sendByte":
                        self.result[intf_name][
                            'Outbound octets(bytes)'] = eles.text
                    elif eles.tag == "sendUniPacket":
                        self.result[intf_name][
                            'Outbound unicast(pkts)'] = eles.text
                    elif eles.tag == "sendMutiPacket":
                        self.result[intf_name][
                            'Outbound multicast(pkts)'] = eles.text
                    elif eles.tag == "sendBroadPacket":
                        self.result[intf_name][
                            'Outbound broadcast(pkts)'] = eles.text
                    elif eles.tag == "sendErrorPacket":
                        self.result[intf_name][
                            'Outbound error(pkts)'] = eles.text
                    elif eles.tag == "sendDropPacket":
                        self.result[intf_name][
                            'Outbound drop(pkts)'] = eles.text
    def get_intf_cleared_stat(self, clr_stat, intf_name):
        """Get interface cleared state information"""
        if not intf_name:
            return
        if_type = get_interface_type(intf_name)
        if if_type == 'fcoe-port' or if_type == 'nve' or if_type == 'tunnel' or \
                if_type == 'vbdif' or if_type == 'vlanif':
            return
        if clr_stat:
            for eles in clr_stat:
                if eles.tag in ["inByteRate", "inPacketRate", "outByteRate", "outPacketRate"]:
                    if eles.tag == "inByteRate":
                        self.result[intf_name][
                            'Inbound rate(byte/sec)'] = eles.text
                    elif eles.tag == "inPacketRate":
                        self.result[intf_name][
                            'Inbound rate(pkts/sec)'] = eles.text
                    elif eles.tag == "outByteRate":
                        self.result[intf_name][
                            'Outbound rate(byte/sec)'] = eles.text
                    elif eles.tag == "outPacketRate":
                        self.result[intf_name][
                            'Outbound rate(pkts/sec)'] = eles.text
    def get_all_interface_info(self, intf_type=None):
        """Get interface information all or by interface type"""
        xml_str = CE_NC_GET_INT_STATISTICS % ''
        con_obj = get_nc_config(self.module, xml_str)
        if "<data/>" in con_obj:
            return
        xml_str = con_obj.replace('\r', '').replace('\n', '').\
            replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\
            replace('xmlns="http://www.huawei.com/netconf/vrp"', "")
        # get link status information
        root = ElementTree.fromstring(xml_str)
        intfs_info = root.find("data/ifm/interfaces")
        if not intfs_info:
            return
        intf_name = ''
        flag = False
        for eles in intfs_info:
            if eles.tag == "interface":
                for ele in eles:
                    if ele.tag in ["ifName", "ifDynamicInfo", "ifStatistics", "ifClearedStat"]:
                        if ele.tag == "ifName":
                            intf_name = ele.text.lower()
                            if intf_type:
                                if get_interface_type(intf_name) != intf_type.lower():
                                    break
                                else:
                                    flag = True
                            self.init_interface_data(intf_name)
                            if is_ethernet_port(intf_name):
                                self.get_port_info(intf_name)
                        if ele.tag == "ifDynamicInfo":
                            self.get_intf_dynamic_info(ele, intf_name)
                        elif ele.tag == "ifStatistics":
                            self.get_intf_statistics_info(ele, intf_name)
                        elif ele.tag == "ifClearedStat":
                            self.get_intf_cleared_stat(ele, intf_name)
        if intf_type and not flag:
            self.module.fail_json(
                msg='Error: %s interface type does not exist.' % intf_type.upper())
    def get_interface_info(self):
        """Get interface information"""
        xml_str = CE_NC_GET_INT_STATISTICS % self.interface.upper()
        con_obj = get_nc_config(self.module, xml_str)
        if "<data/>" in con_obj:
            self.module.fail_json(
                msg='Error: %s interface does not exist.' % self.interface.upper())
            return
        xml_str = con_obj.replace('\r', '').replace('\n', '').\
            replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\
            replace('xmlns="http://www.huawei.com/netconf/vrp"', "")
        # get link status information
        root = ElementTree.fromstring(xml_str)
        intf_info = root.find("data/ifm/interfaces/interface")
        if intf_info:
            for eles in intf_info:
                if eles.tag in ["ifDynamicInfo", "ifStatistics", "ifClearedStat"]:
                    if eles.tag == "ifDynamicInfo":
                        self.get_intf_dynamic_info(eles, self.interface)
                    elif eles.tag == "ifStatistics":
                        self.get_intf_statistics_info(eles, self.interface)
                    elif eles.tag == "ifClearedStat":
                        self.get_intf_cleared_stat(eles, self.interface)
    def init_interface_data(self, intf_name):
        """Init interface data"""
        # init link status data
        self.result[intf_name] = dict()
        self.result[intf_name]['Current physical state'] = 'down'
        self.result[intf_name]['Current link state'] = 'down'
        self.result[intf_name]['Current IPv4 state'] = 'down'
        self.result[intf_name]['Current IPv6 state'] = 'down'
        self.result[intf_name]['Inbound octets(bytes)'] = '--'
        self.result[intf_name]['Inbound unicast(pkts)'] = '--'
        self.result[intf_name]['Inbound multicast(pkts)'] = '--'
        self.result[intf_name]['Inbound broadcast(pkts)'] = '--'
        self.result[intf_name]['Inbound error(pkts)'] = '--'
        self.result[intf_name]['Inbound drop(pkts)'] = '--'
        self.result[intf_name]['Inbound rate(byte/sec)'] = '--'
        self.result[intf_name]['Inbound rate(pkts/sec)'] = '--'
        self.result[intf_name]['Outbound octets(bytes)'] = '--'
        self.result[intf_name]['Outbound unicast(pkts)'] = '--'
        self.result[intf_name]['Outbound multicast(pkts)'] = '--'
        self.result[intf_name]['Outbound broadcast(pkts)'] = '--'
        self.result[intf_name]['Outbound error(pkts)'] = '--'
        self.result[intf_name]['Outbound drop(pkts)'] = '--'
        self.result[intf_name]['Outbound rate(byte/sec)'] = '--'
        self.result[intf_name]['Outbound rate(pkts/sec)'] = '--'
        self.result[intf_name]['Speed'] = '--'
    def get_port_info(self, interface):
        """Get port information"""
        if_type = get_interface_type(interface)
        if if_type == 'meth':
            xml_str = CE_NC_GET_PORT_SPEED % interface.lower().replace('meth', 'MEth')
        else:
            xml_str = CE_NC_GET_PORT_SPEED % interface.upper()
        con_obj = get_nc_config(self.module, xml_str)
        if "<data/>" in con_obj:
            return
        xml_str = con_obj.replace('\r', '').replace('\n', '').\
            replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\
            replace('xmlns="http://www.huawei.com/netconf/vrp"', "")
        # get link status information
        root = ElementTree.fromstring(xml_str)
        port_info = root.find("data/devm/ports/port")
        if port_info:
            for eles in port_info:
                if eles.tag == "ethernetPort":
                    for ele in eles:
                        if ele.tag == 'speed':
                            self.result[interface]['Speed'] = ele.text
    def get_link_status(self):
        """Get link status information"""
        if self.param_type == INTERFACE_FULL_NAME:
            self.init_interface_data(self.interface)
            self.get_interface_info()
            if is_ethernet_port(self.interface):
                self.get_port_info(self.interface)
        elif self.param_type == INTERFACE_TYPE:
            self.get_all_interface_info(self.interface)
        else:
            self.get_all_interface_info()
    def get_intf_param_type(self):
        """Get the type of input interface parameter"""


Please complete the code given below. 
/**
 * ***************************************************************************** Copyright (c) 2004,
 * 2006 Subclipse project and others. All rights reserved. This program and the accompanying
 * materials are made available under the terms of the Eclipse Public License v1.0 which accompanies
 * this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * <p>Contributors: Subclipse project committers - initial API and implementation
 * ****************************************************************************
 */
package org.tigris.subversion.subclipse.ui.settings;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IResource;
import org.tigris.subversion.subclipse.core.ISVNLocalResource;
import org.tigris.subversion.subclipse.core.ISVNRemoteResource;
import org.tigris.subversion.subclipse.core.SVNException;
import org.tigris.subversion.subclipse.core.resources.SVNWorkspaceRoot;
import org.tigris.subversion.subclipse.ui.Policy;
import org.tigris.subversion.subclipse.ui.util.LinkList;
import org.tigris.subversion.svnclientadapter.ISVNProperty;
import org.tigris.subversion.svnclientadapter.SVNUrl;
public class ProjectProperties {
  protected String label = "Issue Number:"; // $NON-NLS-1$
  protected String message;
  protected boolean number = false;
  protected String url;
  protected boolean warnIfNoIssue = false;
  protected boolean append = true;
  protected String logregex;
  private static final String URL = "://"; // $NON-NLS-1$
  private static final List<String> propertyFilterList = new ArrayList<String>();
  static {
    propertyFilterList.add("bugtraq:message");
    propertyFilterList.add("bugtraq:label");
    propertyFilterList.add("bugtraq:url");
    propertyFilterList.add("bugtraq:number");
    propertyFilterList.add("bugtraq:warnifnoissue");
    propertyFilterList.add("bugtraq:append");
    propertyFilterList.add("bugtraq:logregex");
  }
  public ProjectProperties() {
    super();
  }
  public boolean isAppend() {
    return append;
  }
  public void setAppend(boolean append) {
    this.append = append;
  }
  public String getLabel() {
    return label;
  }
  public void setLabel(String label) {
    this.label = label;
  }
  public String getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }
  public boolean isNumber() {
    return number;
  }
  public void setNumber(boolean number) {
    this.number = number;
  }
  public String getUrl() {
    return url;
  }
  public void setUrl(String url) {
    this.url = url;
  }
  public boolean isWarnIfNoIssue() {
    return warnIfNoIssue;
  }
  public void setWarnIfNoIssue(boolean warnIfNoIssue) {
    this.warnIfNoIssue = warnIfNoIssue;
  }
  public String getLogregex() {
    return logregex;
  }
  public void setLogregex(String logregex) {
    this.logregex = logregex;
  }
  public String getResolvedMessage(String issue) {
    if (message == null || issue == null) return null;
    return message.replace("%BUGID%", issue); // $NON-NLS-1$
  }
  public String getResolvedUrl(String issue) {
    if (url == null || issue == null) return null;
    return url.replace("%BUGID%", issue); // $NON-NLS-1$
  }
  // Retrieve hyperlink ranges and url's from commit message.
  public LinkList getLinkList(String commitMessage) {
    ArrayList links = new ArrayList();
    ArrayList urls = new ArrayList();
    ArrayList texts = new ArrayList();
    String bugID = "%BUGID%"; // $NON-NLS-1$
    if (logregex != null) {
      String[] resplit = logregex.split("\n");
      String re1 = resplit[0].trim();
      String re2 = resplit.length > 1 ? resplit[1].trim() : null;
      Pattern pre1 = Pattern.compile(re1);
      Matcher matcher1 = pre1.matcher(commitMessage);
      if (re2 == null) {
        while (matcher1.find()) {
          for (int i = 0; i < matcher1.groupCount(); i++) {
            int range[] = {matcher1.start(i + 1), matcher1.end(i + 1) - matcher1.start(i + 1)};
            String url = getResolvedUrl(matcher1.group(i + 1));
            if ((url != null) && (url.trim().length() > 0)) {
              links.add(range);
              urls.add(url);
              texts.add(matcher1.group(i + 1));
            }
          }
        }
      } else {
        Pattern pre2 = Pattern.compile(re2);
        while (matcher1.find()) {
          Matcher matcher2 = pre2.matcher(matcher1.group());
          while (matcher2.find()) {
            for (int i = 0; i < matcher2.groupCount(); i++) {
              int range[] = {
                matcher2.start(i + 1) + matcher1.start(),
                matcher2.end(i + 1) - matcher2.start(i + 1)
              };
              String url = getResolvedUrl(matcher2.group(i + 1));
              if ((url != null) && (url.trim().length() > 0)) {
                links.add(range);
                urls.add(url);
                texts.add(matcher2.group(i + 1));
              }
            }
          }
        }
      }
    } else if (message != null) {
      int index = message.indexOf(bugID);
      if (index != -1) {
        String remainder = null;
        if (message.length() > index + bugID.length())
          remainder = message.substring(index + bugID.length());
        else remainder = "";
        String tag = message.substring(0, index);
        index = commitMessage.indexOf(tag);
        if (index != -1) {
          index = index + tag.length();
          int start = index;
          StringBuffer issue = new StringBuffer();
          while (index < commitMessage.length()) {
            if (commitMessage.substring(index, index + 1).equals(",")) { // $NON-NLS-1$
              int range[] = {start, issue.length()};
              String url = getResolvedUrl(issue.toString());
              if ((url != null) && (url.trim().length() > 0)) {
                links.add(range);
                urls.add(url);
              }
              start = index + 1;
              issue = new StringBuffer();
            } else {
              if (commitMessage.substring(index, index + 1).equals("\n")
                  || commitMessage.substring(index, index + 1).equals("\r"))
                break; //$NON-NLS-1$ //$NON-NLS-2$
              if (commitMessage.substring(index).trim().equals(remainder.trim())) break;
              if (commitMessage.substring(index).startsWith(remainder + "\n")) break;
              if (commitMessage.substring(index, index + 1).equals(" ")) {
                int lineIndex = commitMessage.indexOf("\n", index);
                if (lineIndex == -1) lineIndex = commitMessage.indexOf("\r", index);
                if (lineIndex != -1) {
                  if (commitMessage.substring(index, lineIndex - 1).trim().length() == 0) break;
                }
              }
              issue.append(commitMessage.substring(index, index + 1));
            }
            index++;
          }
          int range[] = {start, issue.length()};
          String url = getResolvedUrl(issue.toString());
          if ((url != null) && (url.trim().length() > 0)) {
            links.add(range);
            urls.add(url);
            texts.add(issue.toString());
          }
        }
      }
    }
    LinkList urlLinks = getUrls(commitMessage);
    int[][] urlRanges = urlLinks.getLinkRanges();
    String[] urlUrls = urlLinks.getUrls();
    for (int i = 0; i < urlRanges.length; i++) {
      links.add(urlRanges[i]);
      urls.add(urlUrls[i]);
    }
    int[][] linkRanges = new int[links.size()][2];
    links.toArray(linkRanges);
    String[] urlArray = new String[urls.size()];
    urls.toArray(urlArray);
    String[] textArray = new String[texts.size()];
    texts.toArray(textArray);
    LinkList linkList = new LinkList(linkRanges, urlArray, textArray);
    return linkList;
  }
  public static LinkList getUrls(String s) {
    int max = 0;
    int i = -1;
    if (s != null) {
      max = s.length();
      i = s.indexOf(URL);
    }
    ArrayList linkRanges = new ArrayList();
    ArrayList links = new ArrayList();
    while (i != -1) {
      while (i != -1) {
        if (Character.isWhitespace(s.charAt(i))
            || s.substring(i, i + 1).equals("\n")) { // $NON-NLS-1$
          i++;
          break;
        }
        i--;
      }
      int start = (i < 0) ? 0 : i;
      // look for the first whitespace character
      boolean found = false;
      i += URL.length();
      while (!found && i < max) {
        found =
            (Character.isWhitespace(s.charAt(i))
                || s.substring(i, i + 1).equals("\n")); // $NON-NLS-1$
        i++;
      }
      if (i != max) i--;
      linkRanges.add(new int[] {start, i - start});
      links.add(s.substring(start, i));
      i = s.indexOf(URL, i);
    }
    return new LinkList(
        (int[][]) linkRanges.toArray(new int[linkRanges.size()][2]),
        (String[]) links.toArray(new String[links.size()]),
        null);
  }
  // Return error message if there are any problems with the issue that was entered.
  public String validateIssue(String issue) {
    if (number) {
      if (!hasOnlyDigits(issue)) return Policy.bind("CommitDialog.number", label); // $NON-NLS-1$
    }
    return null;
  }
  // Helper method to test for all numerics and commas.
  private boolean hasOnlyDigits(String s) {


Please complete the code given below. 
#region AuthorHeader
//
//	Auction version 2.1, by Xanthos and Arya
//
//  Based on original ideas and code by Arya
//
#endregion AuthorHeader
using System;
using System.IO;
using Server;
namespace Arya.Auction
{
	/// <summary>
	/// Summary description for AuctionLog.
	/// </summary>
	public class AuctionLog
	{
		private static StreamWriter m_Writer;
		private static bool m_Enabled = false;
		public static void Initialize()
		{
			if ( AuctionSystem.Running && AuctionConfig.EnableLogging )
			{
				// Create the log writer
				try
				{
					string folder = Path.Combine( Core.BaseDirectory, @"Logs\Auction" );
					if ( ! Directory.Exists( folder ) )
						Directory.CreateDirectory( folder );
					string name = string.Format( "{0}.txt", DateTime.UtcNow.ToLongDateString() );
					string file = Path.Combine( folder, name );
					m_Writer = new StreamWriter( file, true );
					m_Writer.AutoFlush = true;
					m_Writer.WriteLine( "###############################" );
					m_Writer.WriteLine( "# {0} - {1}", DateTime.UtcNow.ToShortDateString(), DateTime.UtcNow.ToShortTimeString() );
					m_Writer.WriteLine();
					
					m_Enabled = true;
				}
				catch ( Exception err )
				{
					Console.WriteLine( "Couldn't initialize auction system log. Reason:" );
					Console.WriteLine( err.ToString() );
					m_Enabled = false;
				}
			}
		}
		/// <summary>
		/// Records the creation of a new auction item
		/// </summary>
		/// <param name="auction">The new auction</param>
		public static void WriteNewAuction( AuctionItem auction )
		{
			if ( !m_Enabled || m_Writer == null )
				return;
			try
			{
				m_Writer.WriteLine( "## New Auction : {0}", auction.ID );
				m_Writer.WriteLine( "# {0}", auction.ItemName );
				m_Writer.WriteLine( "# Created on {0} at {1}", DateTime.UtcNow.ToShortDateString(), DateTime.UtcNow.ToShortTimeString() );
				m_Writer.WriteLine( "# Owner : {0} [{1}] Account: {2}", auction.Owner.Name, auction.Owner.Serial.ToString(), auction.Account.Username );
				m_Writer.WriteLine( "# Expires on {0} at {1}", auction.EndTime.ToShortDateString(), auction.EndTime.ToShortTimeString() );
				m_Writer.WriteLine( "# Starting Bid: {0}. Reserve: {1}. Buy Now: {2}",
					auction.MinBid, auction.Reserve, auction.AllowBuyNow ? auction.BuyNow.ToString() : "Disabled" );
				m_Writer.WriteLine( "# Owner Description : {0}", auction.Description );
				m_Writer.WriteLine( "# Web Link : {0}", auction.WebLink != null ? auction.WebLink : "N/A" );
			
				if ( auction.Creature )
				{
					// Selling a pet
					m_Writer.WriteLine( "#### Selling 1 Creature" );
					m_Writer.WriteLine( "# Type : {0}. Serial : {1}. Name : {2} Hue : {3}", auction.Pet.GetType().Name, auction.Pet.Serial.ToString(), auction.Pet.Name != null ? auction.Pet.Name : "Unnamed", auction.Pet.Hue );
					m_Writer.WriteLine( "# Statuette Serial : {0}", auction.Item.Serial.ToString() );
					m_Writer.WriteLine( "# Properties: {0}", auction.Items[ 0 ].Properties );
				}
				else
				{
					// Selling items
					m_Writer.WriteLine( "#### Selling {0} Items", auction.ItemCount );
					for ( int i = 0; i < auction.ItemCount; i++ )
					{
						AuctionItem.ItemInfo info = auction.Items[ i ];
						m_Writer.WriteLine( "# {0}. {1} [{2}] Type {3} Hue {4}", i, info.Name, info.Item.Serial, info.Item.GetType().Name, info.Item.Hue );
						m_Writer.WriteLine( "Properties: {0}", info.Properties );
					}
				}
				m_Writer.WriteLine();
			}
			catch {}
		}
		/// <summary>
		/// Writes the current highest bid in an auction
		/// </summary>
		/// <param name="auction">The auction corresponding to the bid</param>
		public static void WriteBid( AuctionItem auction )
		{
			if ( !m_Enabled || m_Writer == null )
				return;
			try
			{
				m_Writer.WriteLine( "> [{0}] Bid Amount : {1}, Mobile : {2} [{3}] Account : {4}",
					auction.ID.ToString(),
					auction.HighestBidValue.ToString("#,0" ),
					auction.HighestBidder.Name,
					auction.HighestBidder.Serial.ToString(),
					( auction.HighestBidder.Account as Server.Accounting.Account ).Username );
			}
			catch {}
		}
		/// <summary>
		/// Changes the
		/// </summary>
		/// <param name="auction">The auction switching to pending</param>
		/// <param name="reason">The reason why the auction is set to pending</param>
		public static void WritePending( AuctionItem auction, string reason )
		{
			if ( !m_Enabled || m_Writer == null )
				return;
			try
			{
				m_Writer.WriteLine( "] [{0}] Becoming Pending on {1} at {2}. Reason : {3}",
					auction.ID.ToString(),
					DateTime.UtcNow.ToShortDateString(),
					DateTime.UtcNow.ToShortTimeString(),
					reason );
			}
			catch {}
		}
		/// <summary>
		/// Writes the end of the auction to the log
		/// </summary>
		/// <param name="auction">The auction ending</param>
		/// <param name="reason">The AuctionResult stating why the auction is ending</param>
		/// <param name="m">The Mobile forcing the end of the auction (can be null)</param>
		/// <param name="comments">Additional comments on the ending (can be null)</param>
		public static void WriteEnd( AuctionItem auction, AuctionResult reason, Mobile m, string comments )
		{
			if ( !m_Enabled || m_Writer == null )
				return;
			try
			{
				m_Writer	.WriteLine( "## Ending Auction {0}", auction.ID.ToString() );
				m_Writer	.WriteLine( "# Status : {0}", reason.ToString() );
				if ( m != null )
					m_Writer	.WriteLine( "# Ended by {0} [{1}], {2}, Account : {3}",
						m.Name, m.Serial.ToString(), m.AccessLevel.ToString(), ( m.Account as Server.Accounting.Account ).Username );
				if ( comments != null )
					m_Writer	.WriteLine( "# Comments : {0}", comments );
				m_Writer	.WriteLine();
			}
			catch {}
		}
		/// <summary>
		/// Records a staff member viewing an item
		/// </summary>
		/// <param name="auction">The auction item</param>
		/// <param name="m">The mobile viewing the item</param>
		public static void WriteViewItem( AuctionItem auction, Mobile m )
		{
			if ( !m_Enabled || m_Writer == null )
				return;
			try
			{
				m_Writer	.WriteLine( "} Vieweing item [{0}] Mobile: {1} [2], {3}, Account : {4}",
					auction.ID.ToString(),
					m.Name,
					m.Serial.ToString(),
					m.AccessLevel.ToString(),
					( m.Account as Server.Accounting.Account ).Username );
			}
			catch {}
		}
		/// <summary>
		/// Records a staff member returning an item
		/// </summary>
		/// <param name="auction">The auction</param>
		/// <param name="m">The mobile returning the item</param>
		public static void WriteReturnItem( AuctionItem auction, Mobile m )
		{
			if ( !m_Enabled || m_Writer == null )
				return;
			try
			{
				m_Writer	.WriteLine( "} Returning item [{0}] Mobile: {1} [2], {3}, Account : {4}",
					auction.ID.ToString(),
					m.Name,
					m.Serial.ToString(),
					m.AccessLevel.ToString(),


Please complete the code given below. 
package no.ntnu.medisn.egenvar;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import javax.swing.JOptionPane;
/**
 ************************************************************************
 * Copyright (C) 2008 Ian Donaldson This file is part of iRefIndex: iRefIndex: A
 * consolidated protein interaction database with provenance iRefIndex is free
 * software: you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or any later version. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received
 * a copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>. PROGRAM: iRefIndex. AUTHORS: Sabry Razick and
 * Ian Donaldson DESCRIPTION: This software collects, consolidates, analayzes
 * and distributes biomolecular interaction data. See http://irefindex.uio.no
 * for more details. REVISION/CONTRIBUTION NOTES: July 10, 2008 Release 1.1.
 * CONTACT: Ian Donaldson Biotechnology Centre of Oslo, P.O. Box 1125, Blindern,
 * 0317, Oslo, Norway. ian.donaldson@biotek.uio.no http://iRefIndex.uio.no
 * PUBLICATION TO CITE:PMID=18823568 iRefIndex: A consolidated protein
 * interaction database with provenance Sabry Razick, George Magklaras and Ian M
 * Donaldson, BMC Bioinformatics. 2008 Sep 30;9:405
 *
 */
public class PathFinder10 {
    private ArrayList<ArrayList<Integer>> selected_patth_ll;
    private ArrayList<ArrayList<Integer>> optimal_pathe_ll;
    private ArrayList<Integer> targets_nehgbours_l;
    private ArrayList<Integer> garbage_sead_l;
    int c_min = 999999999;
    private HashMap<Integer, ArrayList<Integer>> nodemap_bkup;
    public static boolean negetived = false;
    private boolean colpseHubs;
    private boolean expand;
    private int maximum_distance = 99;
    private final int MAX_SIGNIFICANT_HUB_CUT_OFF = 999;
    private int numberOfLargehubs = 0;
    private double avgOfHubs = 0;
    private final int WARNING_HUB_MARGIN = 2294;
    private final int WARNING_HUB_size = 200;
    private int ignor_bigHub_lastDecision = 0;
    public static boolean force_kill_path = false;
    private boolean revers_recomended = false;
    private static boolean firstResult_returned = false;
    public PathFinder10() {
        selected_patth_ll = new ArrayList<ArrayList<Integer>>(100);
        optimal_pathe_ll = new ArrayList<ArrayList<Integer>>(100);
        targets_nehgbours_l = new ArrayList<Integer>(100);
        garbage_sead_l = new ArrayList<Integer>();
        ignor_bigHub_lastDecision = 0;
        numberOfLargehubs = 0;
        avgOfHubs = 0;
        force_kill_path = false;
    }
    public void reSet() {
        selected_patth_ll = new ArrayList<ArrayList<Integer>>(100);
        optimal_pathe_ll = new ArrayList<ArrayList<Integer>>(100);
        targets_nehgbours_l = new ArrayList<Integer>(100);
        garbage_sead_l = new ArrayList<Integer>();
        ignor_bigHub_lastDecision = 0;
        numberOfLargehubs = 0;
        avgOfHubs = 0;
        force_kill_path = false;
    }
    public static void main(String[] args) {
    }
    public ArrayList<ArrayList<String>> getPaths(HashMap<String, ArrayList<String>> connection_map, String start, String stop, int hubColLimit) {
        ArrayList<String> key_l = new ArrayList<String>(connection_map.keySet());
        HashMap<Integer, ArrayList<Integer>> transformed_map = new HashMap<Integer, ArrayList<Integer>>();
        int start_int = -1;
        int stop_int = -1;
        for (int i = 0; i < key_l.size(); i++) {
            ArrayList<String> c_nodes_l = connection_map.get(key_l.get(i));
            if (c_nodes_l != null) {
                ArrayList<Integer> trans_nodes_l = new ArrayList<Integer>(c_nodes_l.size());
                for (int j = 0; j < c_nodes_l.size(); j++) {
                    int tr_val = key_l.indexOf(c_nodes_l.get(j));
                    if (tr_val >= 0) {
                        if (!trans_nodes_l.contains(tr_val)) {
                            trans_nodes_l.add(tr_val);
                        }
                    } else {
                        key_l.add(c_nodes_l.get(j));
                        tr_val = key_l.indexOf(c_nodes_l.get(j));
                        if (!trans_nodes_l.contains(tr_val)) {
                            trans_nodes_l.add(tr_val);
                        }
                    }
                }
                transformed_map.put(i, trans_nodes_l);
            }
        }
        for (int i = 0; i < key_l.size(); i++) {
            if (start.equals(key_l.get(i))) {
                start_int = i;
            } else if (stop.equals(key_l.get(i))) {
                stop_int = i;
            }
        }
        ArrayList<Integer> transformed_map_key_list = new ArrayList<Integer>(transformed_map.keySet());
        for (int i = 0; i < transformed_map_key_list.size(); i++) {
            ArrayList<Integer> neigb_list = transformed_map.get(transformed_map_key_list.get(i));
            for (int j = 0; j < neigb_list.size(); j++) {
                if (transformed_map.get(neigb_list.get(j)) == null) {
                    ArrayList<Integer> tmp = new ArrayList<Integer>(1);
                    tmp.add(transformed_map_key_list.get(i));
                    transformed_map.put(neigb_list.get(j), tmp);
//                    neigb_list.add(neigb_list.get(j));
                } else {
                    if (!transformed_map.get(neigb_list.get(j)).contains(transformed_map_key_list.get(i))) {
                        transformed_map.get(neigb_list.get(j)).add(transformed_map_key_list.get(i));
                    }
                }
            }
        }
        if (start.equals(stop)) {
            ArrayList<ArrayList<String>> dummy_ll = new ArrayList<ArrayList<String>>(1);
            ArrayList<String> dummy_l = new ArrayList<String>(1);
            dummy_l.add(start);
            dummy_ll.add(dummy_l);
            return dummy_ll;
        } else {
            ArrayList<Integer> avoid_l = new ArrayList<Integer>(1);
            int hub_cutoff = 999;
            boolean blok_superErode_neighbors = true;
            find_REDUNT_(transformed_map, start_int, stop_int, hubColLimit, colpseHubs, expand, avoid_l, hub_cutoff, blok_superErode_neighbors);
            ArrayList<ArrayList<String>> selected_patth_string_ll = new ArrayList<ArrayList<String>>(selected_patth_ll.size());
            for (int i = 0; i < selected_patth_ll.size(); i++) {
                ArrayList<Integer> c_list = selected_patth_ll.get(i);
                ArrayList<String> c_trans_list = new ArrayList<String>(c_list.size());
                for (int j = 0; j < c_list.size(); j++) {
                    c_trans_list.add(key_l.get(c_list.get(j)));
                }
                selected_patth_string_ll.add(c_trans_list);
            }
            return selected_patth_string_ll;
        }
    }
    public ArrayList<ArrayList<Integer>> getPaths(int[][] edges, int start, int stop, int hubColLimit, boolean negetived, boolean colpseHubs, boolean expand, ArrayList<Integer> avoid_l, int maximum_distance, int hub_cutoff, boolean blok_superErode_neighbors) {
        reSet();
        this.maximum_distance = maximum_distance;
//        this.minimum_distance = minimum_distance;
        this.colpseHubs = colpseHubs;
        this.expand = expand;
        PathFinder10.negetived = negetived;
        if (negetived) {
            start = start * (-1);
            stop = stop * (-1);
        }
        if (start == stop) {
            ArrayList<ArrayList<Integer>> dummy_ll = new ArrayList<ArrayList<Integer>>(1);
            ArrayList<Integer> dummy_l = new ArrayList<Integer>(1);
            dummy_l.add(start);
            dummy_ll.add(dummy_l);
            return dummy_ll;
        } else {
            find_REDUNT(edges, start, stop, hubColLimit, colpseHubs, expand, avoid_l, hub_cutoff, blok_superErode_neighbors);
            if (negetived) {
                ArrayList<ArrayList<Integer>> selected_patth_negated_ll = new ArrayList<ArrayList<Integer>>(selected_patth_ll.size());
                for (int i = 0; i < selected_patth_ll.size(); i++) {
                    ArrayList<Integer> tmp = selected_patth_ll.remove(i);
                    ArrayList<Integer> negatedt_l = new ArrayList<Integer>(tmp.size());
                    for (int j = 0; j < tmp.size(); j++) {
                        negatedt_l.add(tmp.get(j) * (-1));
                    }
                    selected_patth_negated_ll.add(negatedt_l);
                }
                return selected_patth_negated_ll;
            } else {
                return selected_patth_ll;
            }
        }
    }
    public HashMap<Integer, ArrayList<Integer>> find_REDUNT(int[][] edges, int start, int stop, int hub_threshld, boolean colpseHubs, boolean expand, ArrayList<Integer> avoid_l, int hub_cutoff, boolean blok_superErode_neighbors) {
        HashMap<Integer, ArrayList<Integer>> nodemap = GetNodemap(edges, true);
        return find_REDUNT_(nodemap, start, stop, hub_threshld, colpseHubs, expand, avoid_l, hub_cutoff, blok_superErode_neighbors);
    }
    public HashMap<Integer, ArrayList<Integer>> find_REDUNT_(HashMap<Integer, ArrayList<Integer>> nodemap, int start, int stop, int hub_threshld, boolean colpseHubs, boolean expand, ArrayList<Integer> avoid_l, int hub_cutoff, boolean blok_superErode_neighbors) {
        if (nodemap.containsKey(start) && nodemap.containsKey(stop)) {
            for (int i = 0; i < avoid_l.size(); i++) {
                nodemap.remove(avoid_l.get(i));
            }
            if (hub_cutoff < MAX_SIGNIFICANT_HUB_CUT_OFF) {
                ArrayList<Integer> map_keys = new ArrayList<Integer>(nodemap.keySet());
                for (int i = 0; i < map_keys.size(); i++) {
                    if (nodemap.get(map_keys.get(i)).size() >= hub_cutoff) { //&& !nodemap.get(map_keys.get(i)).contains(start) && !nodemap.get(map_keys.get(i)).contains(stop)
                        if (map_keys.get(i) != start && map_keys.get(i) != stop && !(nodemap.get(map_keys.get(i)).contains(start)) && !(nodemap.get(map_keys.get(i)).contains(stop))) {
                            nodemap.remove(map_keys.get(i));
                        }
                    }
                }
            }
            resolve(nodemap, start, stop, hub_threshld, true, colpseHubs, blok_superErode_neighbors);
            if (expand && !force_kill_path) {
                expand_collapsed(hub_threshld);
            }
            return null;
        }
        return null;
    }
    private void resolve(HashMap<Integer, ArrayList<Integer>> nodemap, Integer start, Integer stop, int hub_threshld, boolean initial, boolean colpseHubs, boolean blok_superErode_neighbors) {
        //System.out.println("Path filling initializing. size of network=" + nodemap.size() + " start=" + start + " stop=" + stop);
        revers_recomended = false;
        if (!force_kill_path) {
            //System.out.println("Path filling erosion step 1. size of network=" + nodemap.size() + " start=" + start + " stop=" + stop);
            nodemap = eroder(nodemap, start, stop);
        }
        //System.out.println("Size of sub-network after erosion step 1=" + nodemap.size() );
        if (!force_kill_path) {
            //System.out.println("Analysing for alternative starting points=" + nodemap.size() + " start=" + start + " stop=" + stop);
            nodemap = stratStopReversalCheck(nodemap, start, stop);
        }
        int original_start = start;
        int original_stop = stop;
        if (revers_recomended) {
            start = stop;
            stop = original_start;
        }
        //System.out.println("Size of sub-network after step 2=" + nodemap.size() );
        //System.out.println("number of hubs larger than 200 connections=" + numberOfLargehubs );
        if (ignor_bigHub_lastDecision == 0 && (numberOfLargehubs > WARNING_HUB_MARGIN)) {
            Object[] possibleValues = {"1) Avoid this hubs and locate a path", "2) Proceed with current operation using existing settings", "3) Quit, change parameters and search again"};
//            if (selectedValue.contains("1)")) {
//                ignor_bigHub_lastDecision = 1;
//            } else if (selectedValue.contains("2)")) {
            ignor_bigHub_lastDecision = 2;
//            } else {
//                ignor_bigHub_lastDecision = 3;
//            }
        }
        if (ignor_bigHub_lastDecision == 1) {
            ignor_bigHub_lastDecision = 2;
            ArrayList<Integer> map_keys = new ArrayList<Integer>(nodemap.keySet());
            for (int i = 0; i < map_keys.size(); i++) {
                if (nodemap.get(map_keys.get(i)).size() >= WARNING_HUB_size) {
                    if (map_keys.get(i) != start && map_keys.get(i) != stop && !(nodemap.get(map_keys.get(i)).contains(start)) && !(nodemap.get(map_keys.get(i)).contains(stop))) {
                        nodemap.remove(map_keys.get(i));
                    }
                }
            }
            nodemap = stratStopReversalCheck(nodemap, start, stop);
        }
        if (ignor_bigHub_lastDecision == 0 || ignor_bigHub_lastDecision == 1 || ignor_bigHub_lastDecision == 2) {
            if (!force_kill_path) {
                //System.out.println("Path filling supper erosion step 4. size of network=" + nodemap.size() + " start=" + start + " stop=" + stop);
                nodemap = superErode_values(nodemap);
            }
            if (!force_kill_path) {
                //System.out.println("Path filling neighbour trimming step 5. size of network=" + nodemap.size() + " start=" + start + " stop=" + stop);
                nodemap = superErode_neighbors(nodemap, start, stop);
            }
            if (initial && !force_kill_path) {
                nodemap_bkup = safecopyMap(nodemap);
            }
            if (!force_kill_path) {
                start = original_start;
                stop = original_stop;
                ArrayList<Integer> maxs = findHub(nodemap, start, stop, hub_threshld);
                boolean removed = maxs.remove(start);
                removed = maxs.remove(stop);
                ArrayList<Integer> sead_l = new ArrayList<Integer>();
                ArrayList<Integer> utilized_sead_l = new ArrayList<Integer>();
                sead_l.add(start);
                ArrayList<ArrayList<Integer>> patth_ll = new ArrayList<ArrayList<Integer>>(500);
                patth_ll.add(new ArrayList(sead_l));
                boolean complete = false;
                int rounds = 0;
                while (!complete || force_kill_path) {
                    rounds++;
                    complete = true;
                    int init_size = sead_l.size();
                    ArrayList<Integer> tmpsead_l = new ArrayList<Integer>(50);
                    if (colpseHubs && !force_kill_path) {
                        ArrayList<Integer> maxs_cl = new ArrayList<Integer>(maxs);
                        if (sead_l != null) {
                            maxs_cl.retainAll(sead_l);
                            if (maxs_cl.size() > 0) {
                                //System.out.println("Collapsing hubs . size of network=" + nodemap.size() + " Hubs =" + maxs_cl.size());
                                collapHubs(nodemap, maxs_cl, start, stop, hub_threshld);
                                maxs.removeAll(maxs_cl);
                            }
                        }
                    }
                    for (int j = 0; (j < sead_l.size() && !force_kill_path); j++) {
                        Integer c_sead = sead_l.get(j);
                        ArrayList<Integer> sead_partnn_l = null;
                        if (!force_kill_path) {


Please complete the code given below. 
#region License
// Copyright (c) 2006-2007, ClearCanvas Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, 
// are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice, 
//      this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above copyright notice, 
//      this list of conditions and the following disclaimer in the documentation 
//      and/or other materials provided with the distribution.
//    * Neither the name of ClearCanvas Inc. nor the names of its contributors 
//      may be used to endorse or promote products derived from this software without 
//      specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
// OF SUCH DAMAGE.
#endregion
namespace Macro.ImageViewer.Tools.Volume.VTK.View.WinForms
{
	partial class TissueControl
	{
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;
		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}
		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this._visibleCheckBox = new System.Windows.Forms.CheckBox();
			this._presetComboBox = new System.Windows.Forms.ComboBox();
			this._presetLabel = new System.Windows.Forms.Label();
			this._windowLabel = new System.Windows.Forms.Label();
			this._levelLabel = new System.Windows.Forms.Label();
			this._opacityLabel = new System.Windows.Forms.Label();
			this._opacityControl = new Macro.Desktop.View.WinForms.TrackBarUpDown();
			this._windowControl = new Macro.Desktop.View.WinForms.TrackBarUpDown();
			this._levelControl = new Macro.Desktop.View.WinForms.TrackBarUpDown();
			this._surfaceRenderingRadio = new System.Windows.Forms.RadioButton();
			this._volumeRenderingRadio = new System.Windows.Forms.RadioButton();
			this.SuspendLayout();
			// 
			// _visibleCheckBox
			// 
			this._visibleCheckBox.AutoSize = true;
			this._visibleCheckBox.Location = new System.Drawing.Point(17, 13);
			this._visibleCheckBox.Name = "_visibleCheckBox";
			this._visibleCheckBox.Size = new System.Drawing.Size(56, 17);
			this._visibleCheckBox.TabIndex = 0;
			this._visibleCheckBox.Text = "Visible";
			this._visibleCheckBox.UseVisualStyleBackColor = true;
			// 
			// _presetComboBox
			// 
			this._presetComboBox.FormattingEnabled = true;
			this._presetComboBox.Location = new System.Drawing.Point(99, 104);
			this._presetComboBox.Name = "_presetComboBox";
			this._presetComboBox.Size = new System.Drawing.Size(156, 21);
			this._presetComboBox.TabIndex = 1;
			// 
			// _presetLabel
			// 
			this._presetLabel.AutoSize = true;
			this._presetLabel.Location = new System.Drawing.Point(12, 107);
			this._presetLabel.Name = "_presetLabel";
			this._presetLabel.Size = new System.Drawing.Size(37, 13);
			this._presetLabel.TabIndex = 6;
			this._presetLabel.Text = "Preset";
			// 
			// _windowLabel
			// 
			this._windowLabel.AutoSize = true;
			this._windowLabel.Location = new System.Drawing.Point(12, 199);
			this._windowLabel.Name = "_windowLabel";
			this._windowLabel.Size = new System.Drawing.Size(46, 13);
			this._windowLabel.TabIndex = 7;
			this._windowLabel.Text = "Window";
			// 
			// _levelLabel
			// 
			this._levelLabel.AutoSize = true;
			this._levelLabel.Location = new System.Drawing.Point(12, 248);
			this._levelLabel.Name = "_levelLabel";
			this._levelLabel.Size = new System.Drawing.Size(33, 13);
			this._levelLabel.TabIndex = 8;
			this._levelLabel.Text = "Level";
			// 
			// _opacityLabel
			// 
			this._opacityLabel.AutoSize = true;
			this._opacityLabel.Location = new System.Drawing.Point(12, 152);
			this._opacityLabel.Name = "_opacityLabel";
			this._opacityLabel.Size = new System.Drawing.Size(43, 13);
			this._opacityLabel.TabIndex = 9;
			this._opacityLabel.Text = "Opacity";
			// 
			// _opacityControl
			// 
			this._opacityControl.AutoSize = true;
			this._opacityControl.DecimalPlaces = 2;
			this._opacityControl.Location = new System.Drawing.Point(89, 143);
			this._opacityControl.Maximum = new decimal(new int[] {
            100,
            0,
            0,
            0});
			this._opacityControl.Minimum = new decimal(new int[] {
            0,
            0,
            0,
            0});
			this._opacityControl.Name = "_opacityControl";
			this._opacityControl.Size = new System.Drawing.Size(256, 42);
			this._opacityControl.TabIndex = 10;
			this._opacityControl.TrackBarIncrements = 100;
			this._opacityControl.Value = new decimal(new int[] {
            0,
            0,
            0,
            0});
			// 
			// _windowControl
			// 
			this._windowControl.AutoSize = true;
			this._windowControl.DecimalPlaces = 0;
			this._windowControl.Location = new System.Drawing.Point(89, 191);
			this._windowControl.Maximum = new decimal(new int[] {
            100,
            0,
            0,
            0});
			this._windowControl.Minimum = new decimal(new int[] {
            0,
            0,
            0,
            0});
			this._windowControl.Name = "_windowControl";
			this._windowControl.Size = new System.Drawing.Size(256, 42);
			this._windowControl.TabIndex = 11;
			this._windowControl.TrackBarIncrements = 100;
			this._windowControl.Value = new decimal(new int[] {
            0,
            0,
            0,
            0});
			// 
			// _levelControl
			// 
			this._levelControl.AutoSize = true;
			this._levelControl.DecimalPlaces = 0;
			this._levelControl.Location = new System.Drawing.Point(89, 239);
			this._levelControl.Maximum = new decimal(new int[] {
            100,
            0,
            0,
            0});
			this._levelControl.Minimum = new decimal(new int[] {
            0,
            0,
            0,
            0});
			this._levelControl.Name = "_levelControl";
			this._levelControl.Size = new System.Drawing.Size(256, 42);
			this._levelControl.TabIndex = 12;
			this._levelControl.TrackBarIncrements = 100;
			this._levelControl.Value = new decimal(new int[] {
            0,
            0,
            0,
            0});
			// 
			// _surfaceRenderingRadio
			// 
			this._surfaceRenderingRadio.AutoCheck = false;
			this._surfaceRenderingRadio.AutoSize = true;
			this._surfaceRenderingRadio.Location = new System.Drawing.Point(17, 43);
			this._surfaceRenderingRadio.Name = "_surfaceRenderingRadio";
			this._surfaceRenderingRadio.Size = new System.Drawing.Size(114, 17);
			this._surfaceRenderingRadio.TabIndex = 13;
			this._surfaceRenderingRadio.TabStop = true;
			this._surfaceRenderingRadio.Text = "Surface Rendering";
			this._surfaceRenderingRadio.UseVisualStyleBackColor = true;
			// 
			// _volumeRenderingRadio
			// 
			this._volumeRenderingRadio.AutoCheck = false;
			this._volumeRenderingRadio.AutoSize = true;
			this._volumeRenderingRadio.Location = new System.Drawing.Point(17, 66);
			this._volumeRenderingRadio.Name = "_volumeRenderingRadio";
			this._volumeRenderingRadio.Size = new System.Drawing.Size(112, 17);
			this._volumeRenderingRadio.TabIndex = 14;
			this._volumeRenderingRadio.TabStop = true;
			this._volumeRenderingRadio.Text = "Volume Rendering";
			this._volumeRenderingRadio.UseVisualStyleBackColor = true;
			// 
			// TissueControl
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
			this.Controls.Add(this._volumeRenderingRadio);
			this.Controls.Add(this._surfaceRenderingRadio);
			this.Controls.Add(this._visibleCheckBox);
			this.Controls.Add(this._presetLabel);
			this.Controls.Add(this._presetComboBox);
			this.Controls.Add(this._opacityLabel);
			this.Controls.Add(this._opacityControl);
			this.Controls.Add(this._windowLabel);
			this.Controls.Add(this._windowControl);
			this.Controls.Add(this._levelLabel);
			this.Controls.Add(this._levelControl);
			this.Name = "TissueControl";


Please complete the code given below. 
"""
Convert human-editable CSV files into JSON files, used by the web application.
"""
import json
import csv
from io import StringIO
from datetime import datetime
################################################################################
# CONFIG 
# behavior categories to include in the JSON file
categories = set(('G', 'M', 'W', 'C', 'F', 'H', 'I', 'P', 'V',)) #'A', 'L', 'O', 'E', 'S'
# time of first GPS point
firstGPStime = datetime(2014,1,24,5,36,14)
# seconds between each GPS point
intervalseconds = 60
class InFileNames:
    observations = 'behavior observation codes.csv'
    translations = 'behavior code translations.csv'
    mediafeatures = 'media features.json'
    gpstrack = 'GPS track.csv'
    pictures = 'pictures.csv'
    textbubbles = 'text bubbles.csv'
    videos = 'videos.csv'
class OutFileNames:
    behavior = 'behavior.json' # observations + translations
    behaviorcsv = 'behavior observation data.csv'
    media = 'media.js' # pictures, videos, text, media features
tourIntro = {
    'loc': [10.5142232962, -85.3693762701],
    'note': 'intro',
    'data': [],
    'time': '05:30:00',
    }
tourStart = {
    'loc': [10.5142232962, -85.3693762701],
    'note': 'start',
    'data': [],
    'time': '05:30:00',
    }
    
tourEnd = {
    'loc': [10.5143646989, -85.3639992792], #[10.5148555432, -85.3643822484], 
    'note': 'end',
    'data': [],
    'time': '18:10:43',
    }
# monkey patch json encoder to format floats
from json import encoder
encoder.FLOAT_REPR = lambda o: format(o, '.5f')
    
################################################################################
# GPS track
with open(InFileNames.gpstrack) as f:
    reader = csv.reader(f, skipinitialspace=True)
    GPStrack = [(float(lat[:9]), float(lon[:10])) for (lat,lon) in list(reader)[1:]]
def parsetime(timestr):
    """
    Get the time from a string, ignore the date.
    (Return a datetime with the date of the first GPS point.)
    """
    
    # take out the date (get only the last space-separated part)
    timestr = timestr.split()[-1]
    time = datetime.strptime(timestr, '%H:%M:%S').time()
    
    return datetime.combine(firstGPStime.date(), time)
def getTimeInterval(time):
    """
    Get start and end points on the GPS track, of the time interval containing "time".
    """
    
    index = int((time - firstGPStime).total_seconds() / intervalseconds)
    interval = GPStrack[index:index+2]
    
    if len(interval) == 2:
        return interval
    
    # if the time is past the last GPS point, return an interval with just the last GPS point    
    else:
        return (GPStrack[-1], GPStrack[-1])
def getGPSCoords(time):
    """
    Get a geographical point along Winslow Homer's GPS track, by linear interpolation
    """
    
    # get start and stop
    start, stop = getTimeInterval(time)
    
    timediff = (time - firstGPStime).total_seconds()
    proportion = (timediff % intervalseconds) / float(intervalseconds)
    
    latdelta = (stop[0] - start[0])
    lat = (proportion * latdelta) + start[0]
    
    londelta = (stop[1] - start[1])
    lon = (proportion * londelta) + start[1]
    
    return (lat, lon)
def loadTranslationsFile():
    """
    Load the translations file, return a list of dicts with the fields in the file
    """
    
    with open(InFileNames.translations) as f:
        reader = csv.DictReader(f, skipinitialspace=True)
        return list(reader)
def loadObservationFile(translations=None):
    """ 
    Load the observations file, return a list with a dict for each observation
    record, and a set with all of the unique behavior codes.
    
    
    """
    
    # ordered list of observations in file
    observations = [] 
    
    # set of codes we've seen
    codes = set() 
    
    
    with open(InFileNames.observations) as f:
        reader = csv.DictReader(f, skipinitialspace=True)
        
        for line in reader:  
            # look up GPS coordinates from timestamp
            line['loc'] = getGPSCoords(parsetime(line['timestamp']))
        
            # add a 'time' field without the date, to display to user
            line['time'] = line['timestamp'].split()[1]
        
            observations.append(line)
            codes.add(line['code'])
    
    
    return observations, codes
    
    
    
def filterObservationsTranslations():
    """ 
    Return (observations, translations) list containing the intersection 
    (inner join) of the observations and translations, and only in the 
    configured categories.
    """
    
    translations = loadTranslationsFile()
    observations, obs_code_set = loadObservationFile()
    
       
    # Find codes that occur in the observations, and are in the right categories.
    # Make a {code : translation-fields} 2-dimensional dict.
    translations_dict = {
        t['code'] : t
        for t in translations
        if  (t['code'] in obs_code_set)  and  (t['category'].upper() in categories)   }
    
    
    # Find observations that have a translation.
    observations = list(filter(lambda o: o['code'] in translations_dict, observations))
    
    
    return observations, translations_dict
    
    
    
    
    
def writeBehaviorJSON(observations, translations_dict, tourlist):
    """
    Write behavior JSON file, with observations and translations joined.
    """
    #observations, translations_dict = filterObservationsTranslations()
    
    # join together observations with translations


Please complete the code given below. 
# -*- coding: utf-8 -*-
#!/usr/bin/env python
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007  Donald N. Allingham
# Copyright (C) 2007       Johan Gonqvist <johan.gronqvist@gmail.com>
# Copyright (C) 2007-2009  Gary Burton <gary.burton@zen.co.uk>
# Copyright (C) 2007-2009  Stephane Charette <stephanecharette@gmail.com>
# Copyright (C) 2008-2009  Brian G. Matherly
# Copyright (C) 2008       Jason M. Simanek <jason@bohemianalps.com>
# Copyright (C) 2008-2011  Rob G. Healey <robhealey1@gmail.com>
# Copyright (C) 2010       Doug Blank <doug.blank@gmail.com>
# Copyright (C) 2010       Jakim Friant
# Copyright (C) 2010-2017  Serge Noiraud
# Copyright (C) 2011       Tim G L Lyons
# Copyright (C) 2013       Benny Malengier
# Copyright (C) 2016       Allen Crider
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
"""
Narrative Web Page generator.
Classe:
    StatisticsPage
"""
#------------------------------------------------
# python modules
#------------------------------------------------
from decimal import getcontext
import logging
#------------------------------------------------
# Gramps module
#------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.lib import (Person, Family, Event, Place, Source,
                            Citation, Repository)
from gramps.gen.plug.report import Bibliography
from gramps.gen.utils.file import media_path_full
from gramps.plugins.lib.libhtml import Html
#------------------------------------------------
# specific narrative web import
#------------------------------------------------
from gramps.plugins.webreport.basepage import BasePage
from gramps.plugins.webreport.common import FULLCLEAR
LOG = logging.getLogger(".NarrativeWeb")
getcontext().prec = 8
_ = glocale.translation.sgettext
class StatisticsPage(BasePage):
    """
    Create one page for statistics
    """
    def __init__(self, report, title, step):
        """
        @param: report        -- The instance of the main report class
                                 for this report
        @param: title         -- Is the title of the web page
        """
        import posixpath
        BasePage.__init__(self, report, title)
        self.bibli = Bibliography()
        self.uplink = False
        self.report = report
        # set the file name and open file
        output_file, sio = self.report.create_file("statistics")
        addressbookpage, head, body = self.write_header(_("Statistics"))
        (males,
         females,
         unknown) = self.get_gender(report.database.iter_person_handles())
        step()
        mobjects = report.database.get_number_of_media()
        npersons = report.database.get_number_of_people()
        nfamilies = report.database.get_number_of_families()
        nsurnames = len(set(report.database.surname_list))
        notfound = []
        total_media = 0
        mbytes = "0"
        chars = 0
        for media in report.database.iter_media():
            total_media += 1
            fullname = media_path_full(report.database, media.get_path())
            try:
                chars += posixpath.getsize(fullname)
                length = len(str(chars))
                if chars <= 999999:
                    mbytes = _("less than 1")
                else:
                    mbytes = str(chars)[:(length-6)]
            except OSError:
                notfound.append(media.get_path())
        with Html("div", class_="content", id='EventDetail') as section:
            section += Html("h3", self._("Database overview"), inline=True)
        body += section
        with Html("div", class_="content", id='subsection narrative') as sec11:
            sec11 += Html("h4", self._("Individuals"), inline=True)
        body += sec11
        with Html("div", class_="content", id='subsection narrative') as sec1:
            sec1 += Html("br", self._("Number of individuals") + self.colon +
                         "%d" % npersons, inline=True)
            sec1 += Html("br", self._("Males") + self.colon +
                         "%d" % males, inline=True)
            sec1 += Html("br", self._("Females") + self.colon +
                         "%d" % females, inline=True)
            sec1 += Html("br", self._("Individuals with unknown gender") +
                         self.colon + "%d" % unknown, inline=True)
        body += sec1
        with Html("div", class_="content", id='subsection narrative') as sec2:
            sec2 += Html("h4", self._("Family Information"), inline=True)
            sec2 += Html("br", self._("Number of families") + self.colon +
                         "%d" % nfamilies, inline=True)
            sec2 += Html("br", self._("Unique surnames") + self.colon +
                         "%d" % nsurnames, inline=True)
        body += sec2
        with Html("div", class_="content", id='subsection narrative') as sec3:
            sec3 += Html("h4", self._("Media Objects"), inline=True)
            sec3 += Html("br",
                         self._("Total number of media object references") +
                         self.colon + "%d" % total_media, inline=True)
            sec3 += Html("br", self._("Number of unique media objects") +
                         self.colon + "%d" % mobjects, inline=True)
            sec3 += Html("br", self._("Total size of media objects") +
                         self.colon +
                         "%8s %s" % (mbytes, self._("Megabyte|MB")),
                         inline=True)
            sec3 += Html("br", self._("Missing Media Objects") +
                         self.colon + "%d" % len(notfound), inline=True)
        body += sec3
        with Html("div", class_="content", id='subsection narrative') as sec4:
            sec4 += Html("h4", self._("Miscellaneous"), inline=True)
            sec4 += Html("br", self._("Number of events") + self.colon +
                         "%d" % report.database.get_number_of_events(),
                         inline=True)
            sec4 += Html("br", self._("Number of places") + self.colon +
                         "%d" % report.database.get_number_of_places(),
                         inline=True)
            nsources = report.database.get_number_of_sources()
            sec4 += Html("br", self._("Number of sources") +
                         self.colon + "%d" % nsources,
                         inline=True)
            ncitations = report.database.get_number_of_citations()
            sec4 += Html("br", self._("Number of citations") +
                         self.colon + "%d" % ncitations,
                         inline=True)
            nrepo = report.database.get_number_of_repositories()
            sec4 += Html("br", self._("Number of repositories") +
                         self.colon + "%d" % nrepo,
                         inline=True)
        body += sec4
        (males,
         females,
         unknown) = self.get_gender(self.report.bkref_dict[Person].keys())
        origin = " :<br/>" + report.filter.get_name(self.rlocale)
        with Html("div", class_="content", id='EventDetail') as section:
            section += Html("h3",
                            self._("Narrative web content report for") + origin,
                            inline=True)
        body += section
        with Html("div", class_="content", id='subsection narrative') as sec5:
            sec5 += Html("h4", self._("Individuals"), inline=True)
            sec5 += Html("br", self._("Number of individuals") + self.colon +
                         "%d" % len(self.report.bkref_dict[Person]),
                         inline=True)
            sec5 += Html("br", self._("Males") + self.colon +
                         "%d" % males, inline=True)
            sec5 += Html("br", self._("Females") + self.colon +
                         "%d" % females, inline=True)
            sec5 += Html("br", self._("Individuals with unknown gender") +
                         self.colon + "%d" % unknown, inline=True)
        body += sec5
        with Html("div", class_="content", id='subsection narrative') as sec6:
            sec6 += Html("h4", self._("Family Information"), inline=True)
            sec6 += Html("br", self._("Number of families") + self.colon +
                         "%d" % len(self.report.bkref_dict[Family]),
                         inline=True)
        body += sec6
        with Html("div", class_="content", id='subsection narrative') as sec7:
            sec7 += Html("h4", self._("Miscellaneous"), inline=True)
            sec7 += Html("br", self._("Number of events") + self.colon +
                         "%d" % len(self.report.bkref_dict[Event]),
                         inline=True)
            sec7 += Html("br", self._("Number of places") + self.colon +
                         "%d" % len(self.report.bkref_dict[Place]),
                         inline=True)
            sec7 += Html("br", self._("Number of sources") + self.colon +
                         "%d" % len(self.report.bkref_dict[Source]),
                         inline=True)
            sec7 += Html("br", self._("Number of citations") + self.colon +
                         "%d" % len(self.report.bkref_dict[Citation]),
                         inline=True)
            sec7 += Html("br", self._("Number of repositories") + self.colon +
                         "%d" % len(self.report.bkref_dict[Repository]),
                         inline=True)
        body += sec7
        # add fullclear for proper styling
        # and footer section to page


Please complete the code given below. 
#!/usr/bin/env python
'''
Fly Helicopter in SITL
AP_FLAKE8_CLEAN
'''
from __future__ import print_function
from arducopter import AutoTestCopter
from common import AutoTest
from common import NotAchievedException, AutoTestTimeoutException
from pymavlink import mavutil
from pysim import vehicleinfo
class AutoTestHelicopter(AutoTestCopter):
    sitl_start_loc = mavutil.location(40.072842, -105.230575, 1586, 0)     # Sparkfun AVC Location
    def vehicleinfo_key(self):
        return 'Helicopter'
    def log_name(self):
        return "HeliCopter"
    def default_frame(self):
        return "heli"
    def sitl_start_location(self):
        return self.sitl_start_loc
    def default_speedup(self):
        '''Heli seems to be race-free'''
        return 100
    def is_heli(self):
        return True
    def rc_defaults(self):
        ret = super(AutoTestHelicopter, self).rc_defaults()
        ret[8] = 1000
        ret[3] = 1000 # collective
        return ret
    @staticmethod
    def get_position_armable_modes_list():
        '''filter THROW mode out of armable modes list; Heli is special-cased'''
        ret = AutoTestCopter.get_position_armable_modes_list()
        ret = filter(lambda x : x != "THROW", ret)
        return ret
    def loiter_requires_position(self):
        self.progress("Skipping loiter-requires-position for heli; rotor runup issues")
    def get_collective_out(self):
        servo = self.mav.recv_match(type='SERVO_OUTPUT_RAW', blocking=True)
        chan_pwm = (servo.servo1_raw + servo.servo2_raw + servo.servo3_raw)/3.0
        return chan_pwm
    def rotor_runup_complete_checks(self):
        # Takeoff and landing in Loiter
        TARGET_RUNUP_TIME = 10
        self.zero_throttle()
        self.change_mode('LOITER')
        self.wait_ready_to_arm()
        self.arm_vehicle()
        servo = self.mav.recv_match(type='SERVO_OUTPUT_RAW', blocking=True)
        coll = servo.servo1_raw
        coll = coll + 50
        self.set_parameter("H_RSC_RUNUP_TIME", TARGET_RUNUP_TIME)
        self.progress("Initiate Runup by putting some throttle")
        self.set_rc(8, 2000)
        self.set_rc(3, 1700)
        self.progress("Collective threshold PWM %u" % coll)
        tstart = self.get_sim_time()
        self.progress("Wait that collective PWM pass threshold value")
        servo = self.mav.recv_match(condition='SERVO_OUTPUT_RAW.servo1_raw>%u' % coll, blocking=True)
        runup_time = self.get_sim_time() - tstart
        self.progress("Collective is now at PWM %u" % servo.servo1_raw)
        self.mav.wait_heartbeat()
        if runup_time < TARGET_RUNUP_TIME:
            self.zero_throttle()
            self.set_rc(8, 1000)
            self.disarm_vehicle()
            self.mav.wait_heartbeat()
            raise NotAchievedException("Takeoff initiated before runup time complete %u" % runup_time)
        self.progress("Runup time %u" % runup_time)
        self.zero_throttle()
        self.set_rc(8, 1000)
        self.land_and_disarm()
        self.mav.wait_heartbeat()
    # fly_avc_test - fly AVC mission
    def fly_avc_test(self):
        # Arm
        self.change_mode('STABILIZE')
        self.wait_ready_to_arm()
        self.arm_vehicle()
        self.progress("Raising rotor speed")
        self.set_rc(8, 2000)
        # upload mission from file
        self.progress("# Load copter_AVC2013_mission")
        # load the waypoint count
        num_wp = self.load_mission("copter_AVC2013_mission.txt", strict=False)
        if not num_wp:
            raise NotAchievedException("load copter_AVC2013_mission failed")
        self.progress("Fly AVC mission from 1 to %u" % num_wp)
        self.set_current_waypoint(1)
        # wait for motor runup
        self.delay_sim_time(20)
        # switch into AUTO mode and raise throttle
        self.change_mode('AUTO')
        self.set_rc(3, 1500)
        # fly the mission
        self.wait_waypoint(0, num_wp-1, timeout=500)
        # set throttle to minimum
        self.zero_throttle()
        # wait for disarm
        self.wait_disarmed()
        self.progress("MOTORS DISARMED OK")
        self.progress("Lowering rotor speed")
        self.set_rc(8, 1000)
        self.progress("AVC mission completed: passed!")
    def takeoff(self,
                alt_min=30,
                takeoff_throttle=1700,
                require_absolute=True,
                mode="STABILIZE",
                timeout=120):
        """Takeoff get to 30m altitude."""
        self.progress("TAKEOFF")
        self.change_mode(mode)
        if not self.armed():
            self.wait_ready_to_arm(require_absolute=require_absolute, timeout=timeout)
            self.zero_throttle()
            self.arm_vehicle()
        self.progress("Raising rotor speed")
        self.set_rc(8, 2000)
        self.progress("wait for rotor runup to complete")
        self.wait_servo_channel_value(8, 1660, timeout=10)
        if mode == 'GUIDED':
            self.user_takeoff(alt_min=alt_min)
        else:
            self.set_rc(3, takeoff_throttle)
        self.wait_for_alt(alt_min=alt_min, timeout=timeout)
        self.hover()
        self.progress("TAKEOFF COMPLETE")
    def fly_each_frame(self):
        vinfo = vehicleinfo.VehicleInfo()
        vinfo_options = vinfo.options[self.vehicleinfo_key()]
        known_broken_frames = {
        }
        for frame in sorted(vinfo_options["frames"].keys()):
            self.start_subtest("Testing frame (%s)" % str(frame))
            if frame in known_broken_frames:
                self.progress("Actually, no I'm not - it is known-broken (%s)" %
                              (known_broken_frames[frame]))
                continue
            frame_bits = vinfo_options["frames"][frame]
            print("frame_bits: %s" % str(frame_bits))
            if frame_bits.get("external", False):
                self.progress("Actually, no I'm not - it is an external simulation")
                continue
            model = frame_bits.get("model", frame)
            # the model string for Callisto has crap in it.... we
            # should really have another entry in the vehicleinfo data
            # to carry the path to the JSON.
            actual_model = model.split(":")[0]
            defaults = self.model_defaults_filepath(actual_model)
            if type(defaults) != list:
                defaults = [defaults]
            self.customise_SITL_commandline(
                ["--defaults", ','.join(defaults), ],
                model=model,
                wipe=True,
            )
            self.takeoff(10)
            self.do_RTL()
            self.set_rc(8, 1000)
    def hover(self):
        self.progress("Setting hover collective")
        self.set_rc(3, 1500)
    def fly_heli_poshold_takeoff(self):
        """ensure vehicle stays put until it is ready to fly"""
        self.context_push()
        ex = None
        try:
            self.set_parameter("PILOT_TKOFF_ALT", 700)
            self.change_mode('POSHOLD')
            self.zero_throttle()
            self.set_rc(8, 1000)
            self.wait_ready_to_arm()
            # Arm
            self.arm_vehicle()
            self.progress("Raising rotor speed")
            self.set_rc(8, 2000)
            self.progress("wait for rotor runup to complete")
            self.wait_servo_channel_value(8, 1660, timeout=10)
            self.delay_sim_time(20)
            # check we are still on the ground...
            m = self.mav.recv_match(type='GLOBAL_POSITION_INT', blocking=True)
            max_relalt_mm = 1000


Please complete the code given below. 
#region Copyright & License Information
/*
 * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
 * This file is part of OpenRA, which is free software. It is made
 * available to you under the terms of the GNU General Public License
 * as published by the Free Software Foundation. For more information,
 * see COPYING.
 */
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Network
{
	static class UnitOrders
	{
		static Player FindPlayerByClient(this World world, Session.Client c)
		{
			/* TODO: this is still a hack.
			 * the cases we're trying to avoid are the extra players on the host's client -- Neutral, other MapPlayers,..*/
			return world.Players.FirstOrDefault(
				p => (p.ClientIndex == c.Index && p.PlayerReference.Playable));
		}
		public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
		{
			if (world != null)
			{
				if (!world.WorldActor.TraitsImplementing<IValidateOrder>().All(vo =>
					vo.OrderValidation(orderManager, world, clientId, order)))
					return;
			}
			switch (order.OrderString)
			{
				case "Chat":
					{
						var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
						if (client != null)
						{
							var player = world != null ? world.FindPlayerByClient(client) : null;
							var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
							suffix = client.IsObserver ? " (Spectator)" : suffix;
							Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
						}
						else
							Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
						break;
					}
				case "Message": // Server message
						Game.AddChatLine(Color.White, "Server", order.TargetString);
					break;
				case "Disconnected": /* reports that the target player disconnected */
					{
						var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
						if (client != null)
							client.State = Session.ClientState.Disconnected;
						break;
					}
				case "TeamChat":
					{
						var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
						if (client != null)
						{
							if (world == null)
							{
								if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
									Game.AddChatLine(client.Color.RGB, client.Name + " (Team)",
										order.TargetString);
							}
							else
							{
								var player = world.FindPlayerByClient(client);
								if (player == null) return;
								if ((world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally) || player.WinState == WinState.Lost)
								{
									var suffix = player.WinState == WinState.Lost ? " (Dead)" : " (Team)";
									Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
								}
							}
						}
						break;
					}
				case "StartGame":
					{
						Game.AddChatLine(Color.White, "Server", "The game has started.");
						Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false);
						break;
					}
				case "PauseGame":
					{
						var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
						if (client != null)
						{
							var pause = order.TargetString == "Pause";
							if (orderManager.World.Paused != pause && !world.LobbyInfo.IsSinglePlayer)
							{
								var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
								Game.AddChatLine(Color.White, "", pausetext);
							}
							orderManager.World.Paused = pause;
							orderManager.World.PredictedPaused = pause;
						}
						break;
					}
				case "HandshakeRequest":
					{
						// TODO: Switch to the server's mod if we have it
						// Otherwise send the handshake with our current settings and let the server reject us
						var mod = Game.modData.Manifest.Mod;
						var info = new Session.Client()
						{
							Name = Game.Settings.Player.Name,
							PreferredColor = Game.Settings.Player.Color,
							Color = Game.Settings.Player.Color,
							Country = "random",
							SpawnPoint = 0,
							Team = 0,
							State = Session.ClientState.Invalid
						};
						var response = new HandshakeResponse()
						{
							Client = info,
							Mod = mod.Id,
							Version = mod.Version,
							Password = orderManager.Password
						};
						orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
						break;
					}
				case "ServerError":
					{
						orderManager.ServerError = order.TargetString;
						orderManager.AuthenticationFailed = false;
						break;
					}
				case "AuthenticationError":
					{
						orderManager.ServerError = order.TargetString;
						orderManager.AuthenticationFailed = true;
						break;
					}
				case "SyncInfo":
					{
						orderManager.LobbyInfo = Session.Deserialize(order.TargetString);
						SetOrderLag(orderManager);
						Game.SyncLobbyInfo();
						break;
					}
				case "SyncLobbyClients":
					{
						var clients = new List<Session.Client>();
						var nodes = MiniYaml.FromString(order.TargetString);
						foreach (var node in nodes)
						{
							var strings = node.Key.Split('@');
							if (strings[0] == "Client")
								clients.Add(Session.Client.Deserialize(node.Value));
						}
						orderManager.LobbyInfo.Clients = clients;
						Game.SyncLobbyInfo();
						break;
					}
				case "SyncLobbySlots":
					{
						var slots = new Dictionary<string, Session.Slot>();
						var nodes = MiniYaml.FromString(order.TargetString);
						foreach (var node in nodes)
						{
							var strings = node.Key.Split('@');
							if (strings[0] == "Slot")
							{
								var slot = Session.Slot.Deserialize(node.Value);
								slots.Add(slot.PlayerReference, slot);
							}
						}
						orderManager.LobbyInfo.Slots = slots;
						Game.SyncLobbyInfo();
						break;
					}
				case "SyncLobbyGlobalSettings":
					{
						var nodes = MiniYaml.FromString(order.TargetString);
						foreach (var node in nodes)
						{
							var strings = node.Key.Split('@');


Please complete the code given below. 
package de.uvwxy.packsock;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
/**
 * A class to simplify the transmission of binary data or strings with a tiny packet header. Its payload size is limited
 * by BUFFER_SIZE.
 * 
 * @author Paul Smith code@uvwxy.de
 * 
 */
public class PackSock {
	// 64 Kb packet size should be enough?
	private static final int BUFFER_SIZE = 1024 * 64;
	private static final int BYTES_TO_READ_FOR_SIZE = 4;
	private static final int BYTES_TO_READ_FOR_TYPE = 1;
	private byte[] buffer = new byte[BUFFER_SIZE];
	private int buffer_pointer = 0;
	private int bytes_to_read_for_payload = -1;
	private int bytes_read_size = 0;
	private int bytes_read_type = 0;
	private int bytes_read_payload = 0;
	private String serverIpAddress;
	private int connectionPort;
	private InetAddress serverAddress;
	private SocketReadState state = SocketReadState.READ_NOTHING;
	private static ServerSocket serverListener;
	private boolean isServer = false;
	private Socket clientSocket;
	private Socket serverSocket;
	private BufferedInputStream sock_in;
	private BufferedOutputStream sock_out;
	private Packet bufferedPacket = null;
	private IServerConnectedHook hook = null;
	private long socketID = System.currentTimeMillis();
	private class ListenThread implements Runnable {
		@Override
		public void run() {
			try {
				try {
					serverSocket = serverListener.accept();
				} catch (SocketException se) {
					// TODO: has been killed by serverListener.close() or other reason
					return;
				}
				sock_in = new BufferedInputStream(serverSocket.getInputStream());
				sock_out = new BufferedOutputStream(serverSocket.getOutputStream());
				if (hook != null)
					hook.onServerAcceptedConnection();
			} catch (IOException e) {
				System.out.println("Socket input/output stream broken..");
				e.printStackTrace();
			}
		}
	}
	/**
	 * Initialize this <code>PackSock</code> as a client socket.
	 * 
	 * @param port
	 * @throws IOException
	 */
	public PackSock(int port, IServerConnectedHook hook) throws IOException {
		isServer = true;
		this.hook = hook;
		if (serverListener == null) {
			serverListener = new ServerSocket(port);
			this.connectionPort = port;
		}
		if (port != this.connectionPort) {
			this.connectionPort = port;
			// This does _not_ close previously connected sockets:
			serverListener.close();
			serverListener = new ServerSocket(port);
		}
	}
	/**
	 * Initialize this <code>PackSock</code> as a server socket.
	 * 
	 * @param serverIpAddress
	 * @param port
	 */
	public PackSock(String serverIpAddress, int port) {
		this.serverIpAddress = serverIpAddress;
		this.connectionPort = port;
	}
	/**
	 * Sets this socket into listen mode with a background Thread accepting the connection.
	 * 
	 * @throws IOException
	 */
	public void listen() throws IOException {
		if (!isServer)
			return;
		Thread listener = new Thread(new ListenThread());
		listener.start();
	}
	/**
	 * Tries to connect this socket to the given host as client.
	 * 
	 * @throws Exception
	 */
	public void connect() throws Exception {
		if (isServer)
			return;
		serverAddress = InetAddress.getByName(serverIpAddress);
		if (clientSocket != null)
			if (clientSocket.isConnected())
				clientSocket.close();
		clientSocket = new Socket(serverAddress, connectionPort);
		clientSocket.setSoTimeout(0);
		clientSocket.setKeepAlive(true);
		clientSocket.setTcpNoDelay(true);
		sock_in = new BufferedInputStream(clientSocket.getInputStream());
		sock_out = new BufferedOutputStream(clientSocket.getOutputStream());
		return;
	}
	/**
	 * This method takes the given <code>Packet</code> and sends it through the existing connection.
	 * 
	 * @param p
	 *            the <code>Packet</code> to send. <code>null</code> is not sent.
	 * @throws IOException
	 */
	public void sendPacket(Packet p) throws IOException, SocketException {
		if (p == null || sock_out == null) {
			// should throw exception here!
			return;
		}
		sock_out.write(p.getPayloadLengthBytes());
		sock_out.write(p.getTypeByte());
		sock_out.write(p.getPayloadAsBytes());
		// make sure stream is written out to the target stream
		sock_out.flush();
	}
	/**
	 * This function will block until a <code>Packet</code> is received. This function will not return <code>null</code>
	 * .
	 * 
	 * @return
	 * @throws IOException
	 */
	public Packet blockingReadSocketForPacket() throws IOException {
		Packet buf = null;
		while (buf == null)
			buf = tryReadSocketForPacket();
		return buf;
	}
	/**
	 * This function will try to read packet data from the socket. If not enough data has been received so far
	 * <code>null</code> is returned. Once an entire packet is read from the buffer the <code>Packet</code> is returned.
	 * returned.
	 * 
	 * @throws IOException
	 */
	public Packet tryReadSocketForPacket() throws IOException, SocketException {
		if (sock_in == null) {
			return null;
		}
		switch (state) {
		case READ_PACKET:
			// reset everything
			bytes_read_size = 0;
			bytes_read_type = 0;
			bytes_read_payload = 0;
			buffer_pointer = 0;
		case READ_NOTHING:
			bufferedPacket = new Packet();
		case READING_SIZE:
			// read maximal 4 bytes of size field
			bytes_read_size += sock_in.read(buffer, buffer_pointer, BYTES_TO_READ_FOR_SIZE - bytes_read_size);
			buffer_pointer += bytes_read_size;
			if (bytes_read_size == BYTES_TO_READ_FOR_SIZE) {
				// now we have everything!
				byte[] src = buffer;
				int srcOffset = buffer_pointer - 4;
				int byteCount = 4;
				// reassemble integer
				ByteBuffer b = ByteBuffer.allocate(4).put(src, srcOffset, byteCount);
				b.position(0);
				int size = b.getInt();
				// set bytes_to_read_payload
				bytes_to_read_for_payload = size;
				state = SocketReadState.READING_TYPE;
			}
			break;
		case READING_TYPE:
			bytes_read_type += sock_in.read(buffer, buffer_pointer, BYTES_TO_READ_FOR_TYPE - bytes_read_type);
			buffer_pointer += bytes_read_type;
			if (bytes_read_type == BYTES_TO_READ_FOR_TYPE) {
				// now we have everything!
				byte type = buffer[buffer_pointer - 1];
				bufferedPacket.setT(type);
				state = SocketReadState.READING_PAYLOAD;
			}
			break;
		case READING_PAYLOAD:
			int bytesCurrentlyRead = sock_in.read(buffer, buffer_pointer, bytes_to_read_for_payload
					- bytes_read_payload);
			bytes_read_payload += bytesCurrentlyRead;
			buffer_pointer += bytesCurrentlyRead;
			if (bytes_read_payload == bytes_to_read_for_payload) {
				// now we have everything!
				byte[] src = buffer;
				int srcOffset = buffer_pointer - bytes_to_read_for_payload;
				int byteCount = bytes_to_read_for_payload;
				byte[] buf = new byte[byteCount];


Please complete the code given below. 
/*******************************************************************************
 * Copyright (c) 2010 Oak Ridge National Laboratory.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 ******************************************************************************/
package org.csstudio.opibuilder.runmode;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import org.csstudio.opibuilder.OPIBuilderPlugin;
import org.csstudio.opibuilder.model.DisplayModel;
import org.csstudio.opibuilder.util.SingleSourceHelper;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IElementFactory;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.part.ViewPart;
/** RCP 'View' for display runtime
 *
 *  <p>Similar to an RCP editor it is associated to an 'input',
 *  but provides only a view to that *.opi, executing its content.
 *
 *  <p>Being a 'View' allows save/restore within a 'Perspective'.
 *
 *  <p>RCP distinguishes instances via their secondary view ID.
 *  Each instances has a memento for storing arbitrary data,
 *  which we use for the 'input' (*.opi path and macros).
 *
 *  <p>Secondary view IDs must be unique, they can't simply increment
 *  from "1" each time CSS is started because then a view with a previously
 *  used secondary ID will show the old content.
 *
 *  <p>RCP only triggers <code>saveState</code> for views that are currently
 *  visible, typically on exit.
 *  This view will write the memento info directly to the underlying E4 model
 *  whenever the input changes.
 *
 *  @author Xihui Chen - Original author
 *  @author Kay Kasemir
 */
@SuppressWarnings("nls")
public class OPIView extends ViewPart implements IOPIRuntime
{
    /** View ID registered in plugin.xml for use as a 'default' view.
     *
     *  <p>For views to be displayed in designated
     *  OPIRunnerPerspective.Position,
     *  that Position.name() is added to the basic ID
     */
    public static final String ID = "org.csstudio.opibuilder.opiView";
    /** Debug option, see .options file at plugin root */
    public static final boolean debug = "true".equalsIgnoreCase(Platform.getDebugOption(OPIBuilderPlugin.PLUGIN_ID + "/views"));
    /** Memento tags */
    private static final String TAG_INPUT = "input",
                                TAG_FACTORY_ID = "factory_id",
                                TAG_MEMENTO = "memento";
    protected OPIRuntimeDelegate opiRuntimeDelegate;
    private IViewSite site;
    private IEditorInput input;
    private OPIRuntimeToolBarDelegate opiRuntimeToolBarDelegate;
    private static boolean openFromPerspective = false;
    public OPIView()
    {
        opiRuntimeDelegate = new OPIRuntimeDelegate(this);
    }
    /** @return Unique secondary view ID for this instance of CSS */
    public static String createSecondaryID()
    {
        return UUID.randomUUID().toString();
    }
    @Override
    public void dispose()
    {
        if (opiRuntimeDelegate != null)
        {
            opiRuntimeDelegate.dispose();
            opiRuntimeDelegate = null;
        }
        if (opiRuntimeToolBarDelegate != null)
        {
            opiRuntimeToolBarDelegate.dispose();
            opiRuntimeToolBarDelegate = null;
        }
        super.dispose();
    }
    @Override
    public void init(final IViewSite site, IMemento memento) throws PartInitException
    {
        super.init(site, memento);
        this.site = site;
        if (debug)
            System.out.println(site.getId() + ":" + site.getSecondaryId() + " opened " +
                               (memento == null ? ", no memento" : "with memento"));
        if (memento == null) {
            memento = findMementoFromPlaceholder();
        }
        if (memento == null) {
            return;
        }
        // Load previously displayed input from memento
        final String  factoryID = memento.getString(TAG_FACTORY_ID);
        if (factoryID == null)
        {
            OPIBuilderPlugin.getLogger().log(Level.WARNING, toString() + " has memento with empty factory ID");
            return;
        }
        final IMemento inputMem = memento.getChild(TAG_INPUT);
        final IElementFactory factory = PlatformUI.getWorkbench().getElementFactory(factoryID);
        if (factory == null)
            throw new PartInitException(NLS.bind(
                    "Cannot instantiate input element factory {0} for OPIView",
                    factoryID));
        final IAdaptable element = factory.createElement(inputMem);
        if (!(element instanceof IEditorInput))
            throw new PartInitException("Instead of IEditorInput, " + factoryID + " returned " + element);
        // Set input, but don't persist to memento because we just read it from memento
        setOPIInput((IEditorInput)element, false);
    }
    /**
     * Retrieve memento persisted in MPlaceholder if present.
     * @return memento persisted in the placeholder.
     */
    private IMemento findMementoFromPlaceholder()
    {
        IMemento memento = null;
        MPlaceholder placeholder = findPlaceholder();
        if (placeholder != null) {
            if (placeholder.getPersistedState().containsKey(TAG_MEMENTO))
            {
                String mementoString = placeholder.getPersistedState().get(TAG_MEMENTO);
                memento = loadMemento(mementoString);
            }
        }
        return memento;
    }
    /**
     * Create memento from string.
     * @param mementoString
     * @return
     */
    private IMemento loadMemento(String mementoString)
    {
        StringReader reader = new StringReader(mementoString);
        try
        {
            return XMLMemento.createReadRoot(reader);
        }
        catch (WorkbenchException e)
        {
            OPIBuilderPlugin.getLogger().log(Level.WARNING, "Failed to load memento", e);
            return null;
        }
    }
    /**
     * Find the MPlaceholder corresponding to this MPart in the MPerspective.  This
     * may have persisted information relevant to loading this OPIView.
     * @return corresponding placeholder
     */
    private MPlaceholder findPlaceholder()
    {
        //do not remove casting - RAP 3.0 still needs it
        final IEclipseContext localContext = (IEclipseContext)getViewSite().getService(IEclipseContext.class);
        final MPart part = localContext.get(MPart.class);
        final EModelService service = (EModelService)PlatformUI.getWorkbench().getService(EModelService.class);
        final IEclipseContext globalContext = (IEclipseContext)PlatformUI.getWorkbench().getService(IEclipseContext.class);
        final MApplication app = globalContext.get(MApplication.class);
        final List<MPlaceholder> phs = service.findElements(app, null, MPlaceholder.class, null);
        for (MPlaceholder ph : phs)
        {
            if (ph.getRef() == part)
            {
                return ph;
            }
        }
        return null;
    }
    /** @param input Display file that this view should execute
     *  @param persist Persist the input to memento?
     */
    public void setOPIInput(final IEditorInput input, final boolean persist) throws PartInitException
    {
        if (debug)
        {
            final IViewSite view = getViewSite();
            System.out.println(view.getId() + ":" + view.getSecondaryId() + " displays " + input.getName());
        }
        this.input = input;
        setTitleToolTip(input.getToolTipText());
        opiRuntimeDelegate.init(site, input);


Please complete the code given below. 
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.widgets;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.accessibility.Accessible;
import javax.swing.ComboBoxEditor;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.text.JTextComponent;
/**
 * Class overriding each {@link JComboBox} in JOSM to control consistently the number of displayed items at once.<br>
 * This is needed because of the default Java behaviour that may display the top-down list off the screen (see #7917).
 *
 * @since 5429
 */
public class JosmComboBox extends JComboBox {
    /**
     * The default prototype value used to compute the maximum number of elements to be displayed at once before
     * displaying a scroll bar
     */
    public static final String DEFAULT_PROTOTYPE_DISPLAY_VALUE = "Prototype display value";
    /**
     * Creates a <code>JosmComboBox</code> with a default data model.
     * The default data model is an empty list of objects.
     * Use <code>addItem</code> to add items. By default the first item
     * in the data model becomes selected.
     *
     * @see DefaultComboBoxModel
     */
    public JosmComboBox() {
        this(DEFAULT_PROTOTYPE_DISPLAY_VALUE);
    }
    /**
     * Creates a <code>JosmComboBox</code> with a default data model and
     * the specified prototype display value.
     * The default data model is an empty list of objects.
     * Use <code>addItem</code> to add items. By default the first item
     * in the data model becomes selected.
     *
     * @param prototypeDisplayValue the <code>Object</code> used to compute
     *      the maximum number of elements to be displayed at once before
     *      displaying a scroll bar
     *
     * @see DefaultComboBoxModel
     * @since 5450
     */
    public JosmComboBox(Object prototypeDisplayValue) {
        super();
        init(prototypeDisplayValue);
    }
    /**
     * Creates a <code>JosmComboBox</code> that takes its items from an
     * existing <code>ComboBoxModel</code>. Since the
     * <code>ComboBoxModel</code> is provided, a combo box created using
     * this constructor does not create a default combo box model and
     * may impact how the insert, remove and add methods behave.
     *
     * @param aModel the <code>ComboBoxModel</code> that provides the
     *      displayed list of items
     * @see DefaultComboBoxModel
     */
    public JosmComboBox(ComboBoxModel aModel) {
        super(aModel);
        List<Object> list = new ArrayList<Object>(aModel.getSize());
        for (int i = 0; i<aModel.getSize(); i++) {
            list.add(aModel.getElementAt(i));
        }
        init(findPrototypeDisplayValue(list));
    }
    /**
     * Creates a <code>JosmComboBox</code> that contains the elements
     * in the specified array. By default the first item in the array
     * (and therefore the data model) becomes selected.
     *
     * @param items  an array of objects to insert into the combo box
     * @see DefaultComboBoxModel
     */
    public JosmComboBox(Object[] items) {
        super(items);
        init(findPrototypeDisplayValue(Arrays.asList(items)));
    }
    /**
     * Finds the prototype display value to use among the given possible candidates.
     * @param possibleValues The possible candidates that will be iterated.
     * @return The value that needs the largest display height on screen.
     * @since 5558
     */
    protected Object findPrototypeDisplayValue(Collection<?> possibleValues) {
        Object result = null;
        int maxHeight = -1;
        if (possibleValues != null) {
            // Remind old prototype to restore it later
            Object oldPrototype = getPrototypeDisplayValue();
            // Get internal JList to directly call the renderer
            JList list = getList();
            try {
                // Index to give to renderer
                int i = 0;
                for (Object value : possibleValues) {
                    if (value != null) {
                        // With a "classic" renderer, we could call setPrototypeDisplayValue(value) + getPreferredSize()
                        // but not with TaggingPreset custom renderer that return a dummy height if index is equal to -1
                        // So we explicitely call the renderer by simulating a correct index for the current value
                        Component c = getRenderer().getListCellRendererComponent(list, value, i, true, true);
                        if (c != null) {
                            // Get the real preferred size for the current value
                            Dimension dim = c.getPreferredSize();
                            if (dim.height > maxHeight) {
                                // Larger ? This is our new prototype
                                maxHeight = dim.height;
                                result = value;
                            }
                        }
                    }
                    i++;
                }
            } finally {
                // Restore original prototype
                setPrototypeDisplayValue(oldPrototype);
            }
        }
        return result;
    }
    protected final JList getList() {
        for (int i = 0; i < getUI().getAccessibleChildrenCount(this); i++) {
            Accessible child = getUI().getAccessibleChild(this, i);
            if (child instanceof ComboPopup) {
                return ((ComboPopup)child).getList();
            }
        }
        return null;
    }
    protected void init(Object prototype) {
        if (prototype != null) {
            setPrototypeDisplayValue(prototype);
            int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
            // Compute maximum number of visible items based on the preferred size of the combo box.
            // This assumes that items have the same height as the combo box, which is not granted by the look and feel
            int maxsize = (screenHeight/getPreferredSize().height) / 2;
            // If possible, adjust the maximum number of items with the real height of items
            // It is not granted this works on every platform (tested OK on Windows)
            JList list = getList();
            if (list != null) {
                if (list.getPrototypeCellValue() != prototype) {
                    list.setPrototypeCellValue(prototype);
                }
                int height = list.getFixedCellHeight();
                if (height > 0) {
                    maxsize = (screenHeight/height) / 2;
                }
            }
            setMaximumRowCount(Math.max(getMaximumRowCount(), maxsize));
        }
        // Handle text contextual menus for editable comboboxes
        ContextMenuHandler handler = new ContextMenuHandler();
        addPropertyChangeListener("editable", handler);
        addPropertyChangeListener("editor", handler);
    }
    protected class ContextMenuHandler extends MouseAdapter implements PropertyChangeListener {
        private JTextComponent component;
        private PopupMenuLauncher launcher;
        @Override public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getPropertyName().equals("editable")) {
                if (evt.getNewValue().equals(true)) {
                    enableMenu();
                } else {
                    disableMenu();
                }
            } else if (evt.getPropertyName().equals("editor")) {
                disableMenu();
                if (isEditable()) {
                    enableMenu();
                }
            }
        }
        private void enableMenu() {
            if (launcher == null) {
                ComboBoxEditor editor = getEditor();
                if (editor != null) {
                    Component editorComponent = editor.getEditorComponent();
                    if (editorComponent instanceof JTextComponent) {
                        component = (JTextComponent) editorComponent;
                        component.addMouseListener(this);
                        launcher = TextContextualPopupMenu.enableMenuFor(component);
                    }
                }
            }
        }
        private void disableMenu() {
            if (launcher != null) {
                TextContextualPopupMenu.disableMenuFor(component, launcher);
                launcher = null;
                component.removeMouseListener(this);
                component = null;
            }
        }
        @Override public void mousePressed(MouseEvent e) { processEvent(e); }
        @Override public void mouseReleased(MouseEvent e) { processEvent(e); }
        private void processEvent(MouseEvent e) {


Please complete the code given below. 
import json
from django.core.management import call_command
from django.test import TestCase
from bulk_adding.models import RawPeople
from candidates.tests.uk_examples import UK2015ExamplesMixin
from official_documents.models import OfficialDocument
from parties.tests.factories import PartyFactory
from parties.tests.fixtures import DefaultPartyFixtures
from sopn_parsing.models import ParsedSOPN
from sopn_parsing.helpers import parse_tables
from ynr.apps.sopn_parsing.management.commands.sopn_parsing_parse_tables import (
    Command as ParseTablesCommand,
)
from unittest import skipIf
from pandas import Index, Series
from sopn_parsing.tests import should_skip_pdf_tests
class TestSOPNHelpers(DefaultPartyFixtures, UK2015ExamplesMixin, TestCase):
    def setUp(self):
        PartyFactory(ec_id="PP85", name="UK Independence Party (UKIP)")
    @skipIf(should_skip_pdf_tests(), "Required PDF libs not installed")
    def test_basic_parsing(self):
        self.assertFalse(RawPeople.objects.exists())
        doc = OfficialDocument.objects.create(
            ballot=self.dulwich_post_ballot,
            document_type=OfficialDocument.NOMINATION_PAPER,
            source_url="example.com",
            relevant_pages="all",
        )
        dataframe = json.dumps(
            {
                "0": {
                    "0": "Name of \nCandidate",
                    "1": "BRADBURY \nAndrew John",
                    "2": "COLLINS \nDave",
                    "3": "HARVEY \nPeter John",
                    "4": "JENNER \nMelanie",
                },
                "1": {
                    "0": "Home Address",
                    "1": "10 Fowey Close, \nShoreham by Sea, \nWest Sussex, \nBN43 5HE",
                    "2": "51 Old Fort Road, \nShoreham by Sea, \nBN43 5RL",
                    "3": "76 Harbour Way, \nShoreham by Sea, \nSussex, \nBN43 5HH",
                    "4": "9 Flag Square, \nShoreham by Sea, \nWest Sussex, \nBN43 5RZ",
                },
                "2": {
                    "0": "Description (if \nany)",
                    "1": "Green Party",
                    "2": "Independent",
                    "3": "UK Independence \nParty (UKIP)",
                    "4": "Labour Party",
                },
                "3": {
                    "0": "Name of \nProposer",
                    "1": "Tiffin Susan J",
                    "2": "Loader Jocelyn C",
                    "3": "Hearne James H",
                    "4": "O`Connor Lavinia",
                },
                "4": {
                    "0": "Reason \nwhy no \nlonger \nnominated\n*",
                    "1": "",
                    "2": "",
                    "3": "",
                    "4": "",
                },
            }
        )
        ParsedSOPN.objects.create(
            sopn=doc, raw_data=dataframe, status="unparsed"
        )
        call_command("sopn_parsing_parse_tables")
        self.assertEqual(RawPeople.objects.count(), 1)
        raw_people = RawPeople.objects.get()
        self.assertEqual(
            raw_people.data,
            [
                {"name": "Andrew John Bradbury", "party_id": "PP63"},
                {"name": "Dave Collins", "party_id": "ynmp-party:2"},
                {"name": "Peter John Harvey", "party_id": "PP85"},
                {"name": "Melanie Jenner", "party_id": "PP53"},
            ],
        )
class TestParseTablesUnitTests(TestCase):
    def get_two_name_field_cases(self):
        # this could be updated with more combinations as we come across them
        return [
            {
                "name_fields": ["candidate surname", "candidate forename"],
                "row": {
                    "candidate surname": "BAGSHAW",
                    "candidate forename": "Elaine Sheila",
                    "home address": "1 Foo Street \n London \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
                "ordered_name_fields": [
                    "candidate forename",
                    "candidate surname",
                ],
                "expected_name": "Elaine Sheila Bagshaw",
            },
            {
                "name_fields": ["surname", "other names"],
                "row": {
                    "surname": "BAGSHAW",
                    "other names": "Elaine Sheila",
                    "home address": "1 Foo Street \nLondon \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
                "ordered_name_fields": ["other names", "surname"],
                "expected_name": "Elaine Sheila Bagshaw",
            },
            {
                "name_fields": ["last name", "other names"],
                "row": {
                    "last name": "BAGSHAW",
                    "other names": "Elaine Sheila",
                    "home address": "1 Foo Street \nLondon \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
                "ordered_name_fields": ["other names", "last name"],
                "expected_name": "Elaine Sheila Bagshaw",
            },
            {
                "name_fields": ["candidate forename", "candidate surname"],
                "row": {
                    "candidate forename": "Elaine Sheila",
                    "candidate surname": "BAGSHAW",
                    "home address": "1 Foo Street \n London \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
                "ordered_name_fields": [
                    "candidate forename",
                    "candidate surname",
                ],
                "expected_name": "Elaine Sheila Bagshaw",
            },
        ]
    def get_single_name_field_cases(self):
        return [
            {
                "name_fields": ["name of candidate"],
                "row": {
                    "name of candidate": "BAGSHAW Elaine Sheila",
                    "home address": "1 Foo Street \n London \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
            },
            {
                "name_fields": ["names of candidate"],
                "row": {
                    "names of candidate": "BAGSHAW Elaine Sheila",
                    "home address": "1 Foo Street \nLondon \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
            },
            {
                "name_fields": ["candidate name"],
                "row": {
                    "candidate name": "BAGSHAW Elaine Sheila",
                    "home address": "1 Foo Street \nLondon \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
            },
            {
                "name_fields": ["surname"],
                "row": {
                    "surname": "BAGSHAW Elaine Sheila",
                    "home address": "1 Foo Street \nLondon \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
            },
            {
                "name_fields": ["candidates surname"],
                "row": {
                    "candidates surname": "BAGSHAW Elaine Sheila",
                    "home address": "1 Foo Street \nLondon \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
            },
            {
                "name_fields": ["other name"],
                "row": {
                    "other name": "BAGSHAW Elaine Sheila",
                    "home address": "1 Foo Street \nLondon \nE14 6FW",
                    "description": "London Liberal \nDemocrats",
                    "reason why no longer nominated": "",
                },
            },
        ]
    def test_get_name_single_field(self):
        for case in self.get_single_name_field_cases():
            row = Series(case["row"])
            name_fields = case["name_fields"]
            with self.subTest(name_fields=name_fields):
                assert len(case["name_fields"]) == 1
                name = parse_tables.get_name(row=row, name_fields=name_fields)
                assert name == "Elaine Sheila Bagshaw"
    def test_get_name_two_fields(self):
        for case in self.get_two_name_field_cases():
            row = Series(case["row"])
            name_fields = case["name_fields"]
            with self.subTest(name_fields=name_fields):
                assert len(case["name_fields"]) == 2
                name = parse_tables.get_name(row=row, name_fields=name_fields)
                assert name == case["expected_name"]
    def test_get_name_fields_single(self):
        for case in self.get_single_name_field_cases():
            row = Index(case["row"])
            with self.subTest(row=row):
                name_fields = parse_tables.get_name_fields(row=row)
                assert len(name_fields) == 1
                assert name_fields == case["name_fields"]
    def test_get_name_fields_two(self):
        for case in self.get_two_name_field_cases():
            row = Index(case["row"])
            with self.subTest(row=row):
                name_fields = parse_tables.get_name_fields(row=row)
                assert len(name_fields) == 2
                assert name_fields == case["name_fields"]
    def test_get_name_fields_raises_error(self):
        row = Index({"foo": "Bar"})
        with self.assertRaises(ValueError):
            parse_tables.get_name_fields(row=row)
    def test_order_name_fields(self):
        for case in self.get_two_name_field_cases():
            name_fields = case["name_fields"]
            with self.subTest(name_fields=name_fields):
                result = parse_tables.order_name_fields(name_fields)
                assert result == case["ordered_name_fields"]
    def test_clean_name_replaces_backticks(self):
        name = parse_tables.clean_name("D`SOUZA")
        assert "`" not in name
        assert "'" in name
    def test_clean_name_replaces_newlines(self):
        name = parse_tables.clean_name(
            "A Very Long Name That Splits \nOver Lines"
        )
        assert "\n" not in name
    def test_clean_name_capitalized_last_and_titalized(self):
        name = parse_tables.clean_name("SMITH John")
        assert name == "John Smith"
    def test_clean_last_names(self):
        name = parse_tables.clean_last_names(["MACDONALD", "John"])
        assert name == "MacDonald"
    def test_clean_name_two_word_surnames(self):
        names = [
            ("EDE COOPER \nPalmer", "Palmer Ede Cooper"),
            ("VAN DULKEN \nRichard Michael", "Richard Michael Van Dulken"),
            ("ARMSTRONG LILLEY \nLynne", "Lynne Armstrong Lilley"),
            (
                " D`SOUZA  Aaron Anthony Jose \nHasan",
                "Aaron Anthony Jose Hasan D'Souza",
            ),
            ("Michael James Collins", "Michael James Collins"),
            ("   Michael    James    Collins   ", "Michael James Collins"),
            ("DAVE Nitesh Pravin", "Nitesh Pravin Dave"),
            ("DAVE\nNitesh Pravin", "Nitesh Pravin Dave"),
            ("COOKE Anne-Marie", "Anne-Marie Cooke"),
            ("COOKE\nAnne-Marie", "Anne-Marie Cooke"),
            ("BROOKES-\nDUNCAN\nKaty", "Katy Brookes-Duncan"),
            ("HOUNSOME\nJohn", "John Hounsome"),
            ("O`CONNELL \nStephen John", "Stephen John O'Connell"),


Please complete the code given below. 
"""
This module provides an abstraction for working with XModuleDescriptors
that are stored in a database an accessible using their Location as an identifier
"""
import logging
import re
import json
import datetime
from uuid import uuid4
from pytz import UTC
from collections import namedtuple, defaultdict
import collections
from contextlib import contextmanager
import functools
import threading
from operator import itemgetter
from sortedcontainers import SortedListWithKey
from abc import ABCMeta, abstractmethod
from contracts import contract, new_contract
from xblock.plugin import default_select
from .exceptions import InvalidLocationError, InsufficientSpecificationError
from xmodule.errortracker import make_error_tracker
from xmodule.assetstore import AssetMetadata
from opaque_keys.edx.keys import CourseKey, UsageKey, AssetKey
from opaque_keys.edx.locations import Location  # For import backwards compatibility
from opaque_keys import InvalidKeyError
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xblock.runtime import Mixologist
from xblock.core import XBlock
log = logging.getLogger('edx.modulestore')
new_contract('CourseKey', CourseKey)
new_contract('AssetKey', AssetKey)
new_contract('AssetMetadata', AssetMetadata)
new_contract('XBlock', XBlock)
LIBRARY_ROOT = 'library.xml'
COURSE_ROOT = 'course.xml'
class ModuleStoreEnum(object):
    """
    A class to encapsulate common constants that are used with the various modulestores.
    """
    class Type(object):
        """
        The various types of modulestores provided
        """
        split = 'split'
        mongo = 'mongo'
        xml = 'xml'
    class RevisionOption(object):
        """
        Revision constants to use for Module Store operations
        Note: These values are passed into store APIs and only used at run time
        """
        # both DRAFT and PUBLISHED versions are queried, with preference to DRAFT versions
        draft_preferred = 'rev-opt-draft-preferred'
        # only DRAFT versions are queried and no PUBLISHED versions
        draft_only = 'rev-opt-draft-only'
        # # only PUBLISHED versions are queried and no DRAFT versions
        published_only = 'rev-opt-published-only'
        # all revisions are queried
        all = 'rev-opt-all'
    class Branch(object):
        """
        Branch constants to use for stores, such as Mongo, that have only 2 branches: DRAFT and PUBLISHED
        Note: These values are taken from server configuration settings, so should not be changed without alerting DevOps
        """
        draft_preferred = 'draft-preferred'
        published_only = 'published-only'
    class BranchName(object):
        """
        Branch constants to use for stores, such as Split, that have named branches
        """
        draft = 'draft-branch'
        published = 'published-branch'
        library = 'library'
    class UserID(object):
        """
        Values for user ID defaults
        """
        # Note: we use negative values here to (try to) not collide
        # with user identifiers provided by actual user services.
        # user ID to use for all management commands
        mgmt_command = -1
        # user ID to use for primitive commands
        primitive_command = -2
        # user ID to use for tests that do not have a django user available
        test = -3
    class SortOrder(object):
        """
        Values for sorting asset metadata.
        """
        ascending = 1
        descending = 2
class BulkOpsRecord(object):
    """
    For handling nesting of bulk operations
    """
    def __init__(self):
        self._active_count = 0
    @property
    def active(self):
        """
        Return whether this bulk write is active.
        """
        return self._active_count > 0
    def nest(self):
        """
        Record another level of nesting of this bulk write operation
        """
        self._active_count += 1
    def unnest(self):
        """
        Record the completion of a level of nesting of the bulk write operation
        """
        self._active_count -= 1
    @property
    def is_root(self):
        """
        Return whether the bulk write is at the root (first) level of nesting
        """
        return self._active_count == 1
class ActiveBulkThread(threading.local):
    """
    Add the expected vars to the thread.
    """
    def __init__(self, bulk_ops_record_type, **kwargs):
        super(ActiveBulkThread, self).__init__(**kwargs)
        self.records = defaultdict(bulk_ops_record_type)
class BulkOperationsMixin(object):
    """
    This implements the :meth:`bulk_operations` modulestore semantics which handles nested invocations
    In particular, it implements :meth:`_begin_bulk_operation` and
    :meth:`_end_bulk_operation` to provide the external interface
    Internally, this mixin records the set of all active bulk operations (keyed on the active course),
    and only writes those values when :meth:`_end_bulk_operation` is called.
    If a bulk write operation isn't active, then the changes are immediately written to the underlying
    mongo_connection.
    """
    def __init__(self, *args, **kwargs):
        super(BulkOperationsMixin, self).__init__(*args, **kwargs)
        self._active_bulk_ops = ActiveBulkThread(self._bulk_ops_record_type)
    @contextmanager
    def bulk_operations(self, course_id, emit_signals=True):
        """
        A context manager for notifying the store of bulk operations. This affects only the current thread.
        In the case of Mongo, it temporarily disables refreshing the metadata inheritance tree
        until the bulk operation is completed.
        """
        try:
            self._begin_bulk_operation(course_id)
            yield
        finally:
            self._end_bulk_operation(course_id, emit_signals)
    # the relevant type of bulk_ops_record for the mixin (overriding classes should override
    # this variable)
    _bulk_ops_record_type = BulkOpsRecord
    def _get_bulk_ops_record(self, course_key, ignore_case=False):
        """
        Return the :class:`.BulkOpsRecord` for this course.
        """
        if course_key is None:
            return self._bulk_ops_record_type()
        # Retrieve the bulk record based on matching org/course/run (possibly ignoring case)
        if ignore_case:
            for key, record in self._active_bulk_ops.records.iteritems():
                # Shortcut: check basic equivalence for cases where org/course/run might be None.
                if key == course_key or (
                    key.org.lower() == course_key.org.lower() and
                    key.course.lower() == course_key.course.lower() and
                    key.run.lower() == course_key.run.lower()
                ):
                    return record
        return self._active_bulk_ops.records[course_key.for_branch(None)]
    @property
    def _active_records(self):
        """
        Yield all active (CourseLocator, BulkOpsRecord) tuples.
        """
        for course_key, record in self._active_bulk_ops.records.iteritems():
            if record.active:
                yield (course_key, record)
    def _clear_bulk_ops_record(self, course_key):
        """
        Clear the record for this course
        """
        del self._active_bulk_ops.records[course_key.for_branch(None)]
    def _start_outermost_bulk_operation(self, bulk_ops_record, course_key):
        """
        The outermost nested bulk_operation call: do the actual begin of the bulk operation.
        Implementing classes must override this method; otherwise, the bulk operations are a noop
        """
        pass
    def _begin_bulk_operation(self, course_key):
        """
        Begin a bulk operation on course_key.
        """
        bulk_ops_record = self._get_bulk_ops_record(course_key)
        # Increment the number of active bulk operations (bulk operations
        # on the same course can be nested)
        bulk_ops_record.nest()
        # If this is the highest level bulk operation, then initialize it
        if bulk_ops_record.is_root:
            self._start_outermost_bulk_operation(bulk_ops_record, course_key)
    def _end_outermost_bulk_operation(self, bulk_ops_record, course_key, emit_signals=True):
        """
        The outermost nested bulk_operation call: do the actual end of the bulk operation.
        Implementing classes must override this method; otherwise, the bulk operations are a noop
        """
        pass
    def _end_bulk_operation(self, course_key, emit_signals=True):
        """
        End the active bulk operation on course_key.
        """
        # If no bulk op is active, return
        bulk_ops_record = self._get_bulk_ops_record(course_key)
        if not bulk_ops_record.active:
            return
        bulk_ops_record.unnest()
        # If this wasn't the outermost context, then don't close out the
        # bulk operation.
        if bulk_ops_record.active:
            return
        self._end_outermost_bulk_operation(bulk_ops_record, course_key, emit_signals)
        self._clear_bulk_ops_record(course_key)
    def _is_in_bulk_operation(self, course_key, ignore_case=False):
        """
        Return whether a bulk operation is active on `course_key`.
        """
        return self._get_bulk_ops_record(course_key, ignore_case).active
class EditInfo(object):
    """
    Encapsulates the editing info of a block.
    """
    def __init__(self, **kwargs):
        self.from_storable(kwargs)
        # For details, see caching_descriptor_system.py get_subtree_edited_by/on.
        self._subtree_edited_on = kwargs.get('_subtree_edited_on', None)
        self._subtree_edited_by = kwargs.get('_subtree_edited_by', None)
    def to_storable(self):
        """
        Serialize to a Mongo-storable format.
        """
        return {
            'previous_version': self.previous_version,
            'update_version': self.update_version,
            'source_version': self.source_version,
            'edited_on': self.edited_on,
            'edited_by': self.edited_by,
            'original_usage': self.original_usage,
            'original_usage_version': self.original_usage_version,
        }
    def from_storable(self, edit_info):
        """
        De-serialize from Mongo-storable format to an object.
        """
        # Guid for the structure which previously changed this XBlock.
        # (Will be the previous value of 'update_version'.)
        self.previous_version = edit_info.get('previous_version', None)
        # Guid for the structure where this XBlock got its current field values.
        # May point to a structure not in this structure's history (e.g., to a draft
        # branch from which this version was published).
        self.update_version = edit_info.get('update_version', None)
        self.source_version = edit_info.get('source_version', None)
        # Datetime when this XBlock's fields last changed.
        self.edited_on = edit_info.get('edited_on', None)
        # User ID which changed this XBlock last.
        self.edited_by = edit_info.get('edited_by', None)
        self.original_usage = edit_info.get('original_usage', None)
        self.original_usage_version = edit_info.get('original_usage_version', None)
    def __str__(self):
        return ("EditInfo(previous_version={0.previous_version}, "
                "update_version={0.update_version}, "
                "source_version={0.source_version}, "
                "edited_on={0.edited_on}, "
                "edited_by={0.edited_by}, "
                "original_usage={0.original_usage}, "
                "original_usage_version={0.original_usage_version}, "
                "_subtree_edited_on={0._subtree_edited_on}, "
                "_subtree_edited_by={0._subtree_edited_by})").format(self)
class BlockData(object):
    """
    Wrap the block data in an object instead of using a straight Python dictionary.
    Allows the storing of meta-information about a structure that doesn't persist along with
    the structure itself.
    """
    def __init__(self, **kwargs):
        # Has the definition been loaded?
        self.definition_loaded = False
        self.from_storable(kwargs)
    def to_storable(self):
        """
        Serialize to a Mongo-storable format.
        """
        return {
            'fields': self.fields,
            'block_type': self.block_type,
            'definition': self.definition,
            'defaults': self.defaults,
            'edit_info': self.edit_info.to_storable()
        }
    def from_storable(self, block_data):
        """
        De-serialize from Mongo-storable format to an object.
        """
        # Contains the Scope.settings and 'children' field values.
        # 'children' are stored as a list of (block_type, block_id) pairs.
        self.fields = block_data.get('fields', {})
        # XBlock type ID.
        self.block_type = block_data.get('block_type', None)
        # DB id of the record containing the content of this XBlock.
        self.definition = block_data.get('definition', None)
        # Scope.settings default values copied from a template block (used e.g. when
        # blocks are copied from a library to a course)
        self.defaults = block_data.get('defaults', {})
        # EditInfo object containing all versioning/editing data.
        self.edit_info = EditInfo(**block_data.get('edit_info', {}))
    def __str__(self):
        return ("BlockData(fields={0.fields}, "
                "block_type={0.block_type}, "
                "definition={0.definition}, "
                "definition_loaded={0.definition_loaded}, "
                "defaults={0.defaults}, "
                "edit_info={0.edit_info})").format(self)
new_contract('BlockData', BlockData)
class IncorrectlySortedList(Exception):
    """
    Thrown when calling find() on a SortedAssetList not sorted by filename.
    """
    pass
class SortedAssetList(SortedListWithKey):
    """
    List of assets that is sorted based on an asset attribute.
    """
    def __init__(self, **kwargs):
        self.filename_sort = False
        key_func = kwargs.get('key', None)
        if key_func is None:
            kwargs['key'] = itemgetter('filename')
            self.filename_sort = True
        super(SortedAssetList, self).__init__(**kwargs)
    @contract(asset_id=AssetKey)
    def find(self, asset_id):
        """
        Find the index of a particular asset in the list. This method is only functional for lists
        sorted by filename. If the list is sorted on any other key, find() raises a
        Returns: Index of asset, if found. None if not found.
        """
        # Don't attempt to find an asset by filename in a list that's not sorted by filename.
        if not self.filename_sort:
            raise IncorrectlySortedList()
        # See if this asset already exists by checking the external_filename.
        # Studio doesn't currently support using multiple course assets with the same filename.
        # So use the filename as the unique identifier.
        idx = None
        idx_left = self.bisect_left({'filename': asset_id.path})
        idx_right = self.bisect_right({'filename': asset_id.path})
        if idx_left != idx_right:
            # Asset was found in the list.
            idx = idx_left
        return idx
    @contract(asset_md=AssetMetadata)
    def insert_or_update(self, asset_md):
        """
        Insert asset metadata if asset is not present. Update asset metadata if asset is already present.
        """
        metadata_to_insert = asset_md.to_storable()
        asset_idx = self.find(asset_md.asset_id)
        if asset_idx is None:
            # Add new metadata sorted into the list.
            self.add(metadata_to_insert)
        else:
            # Replace existing metadata.
            self[asset_idx] = metadata_to_insert
class ModuleStoreAssetBase(object):
    """
    The methods for accessing assets and their metadata
    """
    def _find_course_asset(self, asset_key):
        """
        Returns same as _find_course_assets plus the index to the given asset or None. Does not convert
        to AssetMetadata; thus, is internal.
        Arguments:
            asset_key (AssetKey): what to look for
        Returns:
            Tuple of:
            - AssetMetadata[] for all assets of the given asset_key's type
            - the index of asset in list (None if asset does not exist)
        """
        course_assets = self._find_course_assets(asset_key.course_key)
        all_assets = SortedAssetList(iterable=[])
        # Assets should be pre-sorted, so add them efficiently without sorting.
        # extend() will raise a ValueError if the passed-in list is not sorted.
        all_assets.extend(course_assets.setdefault(asset_key.block_type, []))
        idx = all_assets.find(asset_key)
        return course_assets, idx
    @contract(asset_key='AssetKey')
    def find_asset_metadata(self, asset_key, **kwargs):
        """
        Find the metadata for a particular course asset.
        Arguments:
            asset_key (AssetKey): key containing original asset filename
        Returns:
            asset metadata (AssetMetadata) -or- None if not found
        """
        course_assets, asset_idx = self._find_course_asset(asset_key)
        if asset_idx is None:
            return None
        mdata = AssetMetadata(asset_key, asset_key.path, **kwargs)
        all_assets = course_assets[asset_key.asset_type]
        mdata.from_storable(all_assets[asset_idx])
        return mdata
    @contract(
        course_key='CourseKey', asset_type='None | basestring',
        start='int | None', maxresults='int | None', sort='tuple(str,(int,>=1,<=2))|None'
    )
    def get_all_asset_metadata(self, course_key, asset_type, start=0, maxresults=-1, sort=None, **kwargs):
        """
        Returns a list of asset metadata for all assets of the given asset_type in the course.
        Args:
            course_key (CourseKey): course identifier
            asset_type (str): the block_type of the assets to return. If None, return assets of all types.
            start (int): optional - start at this asset number. Zero-based!
            maxresults (int): optional - return at most this many, -1 means no limit
            sort (array): optional - None means no sort
                (sort_by (str), sort_order (str))
                sort_by - one of 'uploadDate' or 'displayname'
                sort_order - one of SortOrder.ascending or SortOrder.descending
        Returns:
            List of AssetMetadata objects.
        """
        course_assets = self._find_course_assets(course_key)
        # Determine the proper sort - with defaults of ('displayname', SortOrder.ascending).
        key_func = None
        sort_order = ModuleStoreEnum.SortOrder.ascending
        if sort:


Please complete the code given below. 
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
namespace Mirror
{
    public class SyncListString : SyncList<string>
    {
        protected override void SerializeItem(NetworkWriter writer, string item) => writer.WriteString(item);
        protected override string DeserializeItem(NetworkReader reader) => reader.ReadString();
    }
    public class SyncListFloat : SyncList<float>
    {
        protected override void SerializeItem(NetworkWriter writer, float item) => writer.WriteSingle(item);
        protected override float DeserializeItem(NetworkReader reader) => reader.ReadSingle();
    }
    public class SyncListInt : SyncList<int>
    {
        protected override void SerializeItem(NetworkWriter writer, int item) => writer.WritePackedInt32(item);
        protected override int DeserializeItem(NetworkReader reader) => reader.ReadPackedInt32();
    }
    public class SyncListUInt : SyncList<uint>
    {
        protected override void SerializeItem(NetworkWriter writer, uint item) => writer.WritePackedUInt32(item);
        protected override uint DeserializeItem(NetworkReader reader) => reader.ReadPackedUInt32();
    }
    public class SyncListBool : SyncList<bool>
    {
        protected override void SerializeItem(NetworkWriter writer, bool item) => writer.WriteBoolean(item);
        protected override bool DeserializeItem(NetworkReader reader) => reader.ReadBoolean();
    }
    // Original UNET name is SyncListStruct and original Weaver weavers anything
    // that contains the name 'SyncListStruct', without considering the name-
    // space.
    [EditorBrowsable(EditorBrowsableState.Never), Obsolete("Use SyncList<MyStruct> instead")]
    public class SyncListSTRUCT<T> : SyncList<T> where T : struct
    {
        public T GetItem(int i) => base[i];
    }
    [EditorBrowsable(EditorBrowsableState.Never)]
    public abstract class SyncList<T> : IList<T>, IReadOnlyList<T>, SyncObject
    {
        public delegate void SyncListChanged(Operation op, int itemIndex, T oldItem, T newItem);
        readonly IList<T> objects;
        readonly IEqualityComparer<T> comparer;
        public int Count => objects.Count;
        public bool IsReadOnly { get; private set; }
        public event SyncListChanged Callback;
        public enum Operation : byte
        {
            OP_ADD,
            OP_CLEAR,
            OP_INSERT,
            [Obsolete("Lists now pass OP_REMOVEAT")]
            OP_REMOVE,
            OP_REMOVEAT,
            OP_SET,
            [Obsolete("Lists now use OP_SET instead of OP_DIRTY")]
            OP_DIRTY
        }
        struct Change
        {
            internal Operation operation;
            internal int index;
            internal T item;
        }
        readonly List<Change> changes = new List<Change>();
        // how many changes we need to ignore
        // this is needed because when we initialize the list,
        // we might later receive changes that have already been applied
        // so we need to skip them
        int changesAhead;
        protected virtual void SerializeItem(NetworkWriter writer, T item) { }
        protected virtual T DeserializeItem(NetworkReader reader) => default;
        protected SyncList(IEqualityComparer<T> comparer = null)
        {
            this.comparer = comparer ?? EqualityComparer<T>.Default;
            objects = new List<T>();
        }
        protected SyncList(IList<T> objects, IEqualityComparer<T> comparer = null)
        {
            this.comparer = comparer ?? EqualityComparer<T>.Default;
            this.objects = objects;
        }
        public bool IsDirty => changes.Count > 0;
        // throw away all the changes
        // this should be called after a successfull sync
        public void Flush() => changes.Clear();
        void AddOperation(Operation op, int itemIndex, T oldItem, T newItem)
        {
            if (IsReadOnly)
            {
                throw new InvalidOperationException("Synclists can only be modified at the server");
            }
            Change change = new Change
            {
                operation = op,
                index = itemIndex,
                item = newItem
            };
            changes.Add(change);
            Callback?.Invoke(op, itemIndex, oldItem, newItem);
        }
        public void OnSerializeAll(NetworkWriter writer)
        {
            // if init,  write the full list content
            writer.WritePackedUInt32((uint)objects.Count);
            for (int i = 0; i < objects.Count; i++)
            {
                T obj = objects[i];
                SerializeItem(writer, obj);
            }
            // all changes have been applied already
            // thus the client will need to skip all the pending changes
            // or they would be applied again.
            // So we write how many changes are pending
            writer.WritePackedUInt32((uint)changes.Count);
        }
        public void OnSerializeDelta(NetworkWriter writer)
        {
            // write all the queued up changes
            writer.WritePackedUInt32((uint)changes.Count);
            for (int i = 0; i < changes.Count; i++)
            {
                Change change = changes[i];
                writer.WriteByte((byte)change.operation);
                switch (change.operation)
                {
                    case Operation.OP_ADD:
                        SerializeItem(writer, change.item);
                        break;
                    case Operation.OP_CLEAR:
                        break;
                    case Operation.OP_REMOVEAT:
                        writer.WritePackedUInt32((uint)change.index);
                        break;
                    case Operation.OP_INSERT:
                    case Operation.OP_SET:
                        writer.WritePackedUInt32((uint)change.index);
                        SerializeItem(writer, change.item);
                        break;
                }
            }
        }
        public void OnDeserializeAll(NetworkReader reader)
        {
            // This list can now only be modified by synchronization
            IsReadOnly = true;
            // if init,  write the full list content
            int count = (int)reader.ReadPackedUInt32();
            objects.Clear();
            changes.Clear();
            for (int i = 0; i < count; i++)
            {
                T obj = DeserializeItem(reader);
                objects.Add(obj);
            }
            // We will need to skip all these changes
            // the next time the list is synchronized
            // because they have already been applied
            changesAhead = (int)reader.ReadPackedUInt32();
        }
        public void OnDeserializeDelta(NetworkReader reader)
        {
            // This list can now only be modified by synchronization
            IsReadOnly = true;
            int changesCount = (int)reader.ReadPackedUInt32();
            for (int i = 0; i < changesCount; i++)
            {
                Operation operation = (Operation)reader.ReadByte();
                // apply the operation only if it is a new change
                // that we have not applied yet
                bool apply = changesAhead == 0;
                int index = 0;
                T oldItem = default;
                T newItem = default;
                switch (operation)
                {
                    case Operation.OP_ADD:
                        newItem = DeserializeItem(reader);
                        if (apply)
                        {
                            index = objects.Count;
                            objects.Add(newItem);
                        }
                        break;
                    case Operation.OP_CLEAR:
                        if (apply)
                        {
                            objects.Clear();
                        }
                        break;
                    case Operation.OP_INSERT:
                        index = (int)reader.ReadPackedUInt32();
                        newItem = DeserializeItem(reader);
                        if (apply)
                        {
                            objects.Insert(index, newItem);
                        }
                        break;
                    case Operation.OP_REMOVEAT:
                        index = (int)reader.ReadPackedUInt32();
                        if (apply)
                        {
                            oldItem = objects[index];
                            objects.RemoveAt(index);
                        }
                        break;
                    case Operation.OP_SET:
                        index = (int)reader.ReadPackedUInt32();
                        newItem = DeserializeItem(reader);
                        if (apply)
                        {
                            oldItem = objects[index];
                            objects[index] = newItem;
                        }
                        break;
                }
                if (apply)
                {
                    Callback?.Invoke(operation, index, oldItem, newItem);
                }
                // we just skipped this change
                else
                {
                    changesAhead--;
                }
            }
        }
        public void Add(T item)
        {
            objects.Add(item);
            AddOperation(Operation.OP_ADD, objects.Count - 1, default, item);
        }
        public void Clear()
        {
            objects.Clear();
            AddOperation(Operation.OP_CLEAR, 0, default, default);
        }
        public bool Contains(T item) => IndexOf(item) >= 0;
        public void CopyTo(T[] array, int index) => objects.CopyTo(array, index);
        public int IndexOf(T item)
        {
            for (int i = 0; i < objects.Count; ++i)
                if (comparer.Equals(item, objects[i]))
                    return i;
            return -1;
        }
        public int FindIndex(Predicate<T> match)
        {
            for (int i = 0; i < objects.Count; ++i)
                if (match(objects[i]))
                    return i;
            return -1;
        }
        public void Insert(int index, T item)
        {
            objects.Insert(index, item);
            AddOperation(Operation.OP_INSERT, index, default, item);
        }
        public bool Remove(T item)
        {
            int index = IndexOf(item);
            bool result = index >= 0;
            if (result)
            {
                RemoveAt(index);
            }
            return result;
        }
        public void RemoveAt(int index)
        {
            T oldItem = objects[index];
            objects.RemoveAt(index);
            AddOperation(Operation.OP_REMOVEAT, index, oldItem, default);
        }
        public T this[int i]
        {
            get => objects[i];
            set
            {
                if (!comparer.Equals(objects[i], value))
                {
                    T oldItem = objects[i];
                    objects[i] = value;
                    AddOperation(Operation.OP_SET, i, oldItem, value);
                }
            }
        }
        public Enumerator GetEnumerator() => new Enumerator(this);
        IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator(this);
        IEnumerator IEnumerable.GetEnumerator() => new Enumerator(this);
        // default Enumerator allocates. we need a custom struct Enumerator to
        // not allocate on the heap.
        // (System.Collections.Generic.List<T> source code does the same)
        //
        // benchmark:
        //   uMMORPG with 800 monsters, Skills.GetHealthBonus() which runs a
        //   foreach on skills SyncList:
        //      before: 81.2KB GC per frame
        //      after:     0KB GC per frame
        // => this is extremely important for MMO scale networking
        public struct Enumerator : IEnumerator<T>
        {
            readonly SyncList<T> list;
            int index;
            public T Current { get; private set; }
            public Enumerator(SyncList<T> list)
            {
                this.list = list;


Please complete the code given below. 
# unionrepo.py - repository class for viewing union of repository changesets
#
# Derived from bundlerepo.py
# Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
# Copyright 2013 Unity Technologies, Mads Kiilerich <madski@unity3d.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
"""Repository class for "in-memory pull" of one local repository to another,
allowing operations like diff and log with revsets.
"""
from node import nullid
from i18n import _
import os
import util, mdiff, cmdutil, scmutil
import localrepo, changelog, manifest, filelog, revlog
class unionrevlog(revlog.revlog):
    def __init__(self, opener, indexfile, revlog2, linkmapper):
        # How it works:
        # To retrieve a revision, we just need to know the node id so we can
        # look it up in revlog2.
        #
        # To differentiate a rev in the second revlog from a rev in the revlog,
        # we check revision against repotiprev.
        opener = scmutil.readonlyvfs(opener)
        revlog.revlog.__init__(self, opener, indexfile)
        self.revlog2 = revlog2
        n = len(self)
        self.repotiprev = n - 1
        self.bundlerevs = set() # used by 'bundle()' revset expression
        for rev2 in self.revlog2:
            rev = self.revlog2.index[rev2]
            # rev numbers - in revlog2, very different from self.rev
            _start, _csize, _rsize, _base, linkrev, p1rev, p2rev, node = rev
            if linkmapper is None: # link is to same revlog
                assert linkrev == rev2 # we never link back
                link = n
            else: # rev must be mapped from repo2 cl to unified cl by linkmapper
                link = linkmapper(linkrev)
            if node in self.nodemap:
                # this happens for the common revlog revisions
                self.bundlerevs.add(self.nodemap[node])
                continue
            p1node = self.revlog2.node(p1rev)
            p2node = self.revlog2.node(p2rev)
            e = (None, None, None, None,
                 link, self.rev(p1node), self.rev(p2node), node)
            self.index.insert(-1, e)
            self.nodemap[node] = n
            self.bundlerevs.add(n)
            n += 1
    def _chunk(self, rev):
        if rev <= self.repotiprev:
            return revlog.revlog._chunk(self, rev)
        return self.revlog2._chunk(self.node(rev))
    def revdiff(self, rev1, rev2):
        """return or calculate a delta between two revisions"""
        if rev1 > self.repotiprev and rev2 > self.repotiprev:
            return self.revlog2.revdiff(
                self.revlog2.rev(self.node(rev1)),
                self.revlog2.rev(self.node(rev2)))
        elif rev1 <= self.repotiprev and rev2 <= self.repotiprev:
            return self.baserevdiff(rev1, rev2)
        return mdiff.textdiff(self.revision(self.node(rev1)),
                              self.revision(self.node(rev2)))
    def revision(self, nodeorrev):
        """return an uncompressed revision of a given node or revision
        number.
        """
        if isinstance(nodeorrev, int):
            rev = nodeorrev
            node = self.node(rev)
        else:
            node = nodeorrev
            rev = self.rev(node)
        if node == nullid:
            return ""
        if rev > self.repotiprev:
            text = self.revlog2.revision(node)
            self._cache = (node, rev, text)
        else:
            text = self.baserevision(rev)
            # already cached
        return text
    def baserevision(self, nodeorrev):
        # Revlog subclasses may override 'revision' method to modify format of
        # content retrieved from revlog. To use unionrevlog with such class one
        # needs to override 'baserevision' and make more specific call here.
        return revlog.revlog.revision(self, nodeorrev)
    def baserevdiff(self, rev1, rev2):
        # Exists for the same purpose as baserevision.
        return revlog.revlog.revdiff(self, rev1, rev2)
    def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
        raise NotImplementedError
    def addgroup(self, revs, linkmapper, transaction):
        raise NotImplementedError
    def strip(self, rev, minlink):
        raise NotImplementedError
    def checksize(self):
        raise NotImplementedError
class unionchangelog(unionrevlog, changelog.changelog):
    def __init__(self, opener, opener2):
        changelog.changelog.__init__(self, opener)
        linkmapper = None
        changelog2 = changelog.changelog(opener2)
        unionrevlog.__init__(self, opener, self.indexfile, changelog2,
                             linkmapper)
    def baserevision(self, nodeorrev):
        # Although changelog doesn't override 'revision' method, some extensions
        # may replace this class with another that does. Same story with
        # manifest and filelog classes.
        return changelog.changelog.revision(self, nodeorrev)
    def baserevdiff(self, rev1, rev2):
        return changelog.changelog.revdiff(self, rev1, rev2)
class unionmanifest(unionrevlog, manifest.manifest):
    def __init__(self, opener, opener2, linkmapper):
        manifest.manifest.__init__(self, opener)
        manifest2 = manifest.manifest(opener2)
        unionrevlog.__init__(self, opener, self.indexfile, manifest2,
                             linkmapper)
    def baserevision(self, nodeorrev):
        return manifest.manifest.revision(self, nodeorrev)
    def baserevdiff(self, rev1, rev2):
        return manifest.manifest.revdiff(self, rev1, rev2)
class unionfilelog(unionrevlog, filelog.filelog):
    def __init__(self, opener, path, opener2, linkmapper, repo):
        filelog.filelog.__init__(self, opener, path)
        filelog2 = filelog.filelog(opener2, path)
        unionrevlog.__init__(self, opener, self.indexfile, filelog2,
                             linkmapper)
        self._repo = repo
    def baserevision(self, nodeorrev):
        return filelog.filelog.revision(self, nodeorrev)
    def baserevdiff(self, rev1, rev2):
        return filelog.filelog.revdiff(self, rev1, rev2)
    def _file(self, f):
        self._repo.file(f)
class unionpeer(localrepo.localpeer):
    def canpush(self):
        return False
class unionrepository(localrepo.localrepository):
    def __init__(self, ui, path, path2):
        localrepo.localrepository.__init__(self, ui, path)
        self.ui.setconfig('phases', 'publish', False, 'unionrepo')
        self._url = 'union:%s+%s' % (util.expandpath(path),
                                     util.expandpath(path2))
        self.repo2 = localrepo.localrepository(ui, path2)
    @localrepo.unfilteredpropertycache
    def changelog(self):
        return unionchangelog(self.sopener, self.repo2.sopener)
    def _clrev(self, rev2):
        """map from repo2 changelog rev to temporary rev in self.changelog"""
        node = self.repo2.changelog.node(rev2)
        return self.changelog.rev(node)
    @localrepo.unfilteredpropertycache
    def manifest(self):
        return unionmanifest(self.sopener, self.repo2.sopener,
                             self._clrev)
    def url(self):
        return self._url
    def file(self, f):
        return unionfilelog(self.sopener, f, self.repo2.sopener,
                            self._clrev, self)
    def close(self):
        self.repo2.close()
    def cancopy(self):
        return False
    def peer(self):
        return unionpeer(self)
    def getcwd(self):
        return os.getcwd() # always outside the repo
def instance(ui, path, create):
    if create:
        raise util.Abort(_('cannot create new union repository'))
    parentpath = ui.config("bundle", "mainreporoot", "")
    if not parentpath:
        # try to find the correct path to the working directory repo
        parentpath = cmdutil.findrepo(os.getcwd())
        if parentpath is None:
            parentpath = ''
    if parentpath:
        # Try to make the full path relative so we get a nice, short URL.
        # In particular, we don't want temp dir names in test outputs.
        cwd = os.getcwd()
        if parentpath == cwd:
            parentpath = ''
        else:
            cwd = os.path.join(cwd,'')
            if parentpath.startswith(cwd):


Please complete the code given below. 
#
# Copyright (c) 2015-2018 Canonical, Ltd.
#
# This file is part of Talisker
# (see http://github.com/canonical-ols/talisker).
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from builtins import *  # noqa
from collections import OrderedDict
from contextlib import contextmanager
import logging
import logging.handlers
import numbers
import sys
import time
from talisker.context import Context, ContextId
from talisker.util import (
    get_errno_fields,
    module_cache,
    module_dict,
)
__all__ = [
    'configure',
    'configure_test_logging',
    'logging_context',
]
logging_globals = module_dict()
def set_global_extra(extra):
    if 'extra' not in logging_globals:
        logging_globals['extra'] = OrderedDict()
    logging_globals['extra'].update(extra)
def reset_logging():
    """Reset logging config"""
    # avoid unclosed file resource warning
    for handler in logging.getLogger().handlers:
        if getattr(handler, '_debug_handler', False):
            handler.stream.close()
    logging.getLogger().handlers = []
NOISY_LOGS = {
    'requests': logging.WARNING,
}
class LoggingContextProxy():
    def __getattr__(self, attr):
        return getattr(Context.logging, attr)
    @contextmanager
    def __call__(self, extra=None, **kwargs):
        with Context.logging(extra, **kwargs):
            yield
logging_context = LoggingContextProxy()
# backwards compat aliases
def set_logging_context(*args, **kwargs):
    Context.logging.push(*args, **kwargs)
extra_logging = logging_context
def add_talisker_handler(level, handler, formatter=None):
    if formatter is None:
        formatter = StructuredFormatter()
    handler.setFormatter(formatter)
    handler.setLevel(level)
    handler._talisker_handler = True
    logging.getLogger().addHandler(handler)
def set_logger_class():
    logging.setLoggerClass(StructuredLogger)
    logging.getLogger().setLevel(logging.NOTSET)
@module_cache
def get_talisker_handler():
    handler = logging.StreamHandler()
    handler._root_talisker = True
    return handler
def configure(config):  # pragma: no cover
    """Configure default logging setup for our services.
    This is basically:
     - log to stderr
     - output hybrid logfmt structured format
     - maybe configure debug logging
    """
    # avoid duplicate logging
    if logging_globals.get('configured'):
        return
    set_logger_class()
    formatter = StructuredFormatter()
    if config.colour:
        formatter = ColouredFormatter(style=config.colour)
    # always INFO to stderr
    add_talisker_handler(logging.INFO, get_talisker_handler(), formatter)
    configure_warnings(config.devel)
    supress_noisy_logs()
    # defer this until logging has been set up
    logger = logging.getLogger(__name__)
    config_extra = {k: v.value for k, v in config.metadata().items() if v.raw}
    if config_extra:
        logger.info('talisker configured', extra=config_extra)
    if config.ERRORS:
        errors = {name: str(err) for name, err in config.ERRORS.items()}
        logger.error('configuration errors', extra=errors)
    if config.debuglog is not None:
        if can_write_to_file(config.debuglog):
            handler = logging.handlers.TimedRotatingFileHandler(
                config.debuglog,
                when='D',
                interval=1,
                backupCount=1,
                delay=True,
                utc=True,
            )
            handler._debug_handler = True
            add_talisker_handler(logging.DEBUG, handler)
            logger.info('enabling debug log', extra={'path': config.debuglog})
        else:
            logger.info('could not enable debug log, could not write to path',
                        extra={'path': config.debuglog})
    # sentry integration
    import talisker.sentry  # defer to avoid logging setup
    if talisker.sentry.enabled:
        sentry_handler = talisker.sentry.get_log_handler()
        add_talisker_handler(logging.ERROR, sentry_handler)
    logging_globals['configured'] = True
def can_write_to_file(path):
    try:
        open(path, 'a').close()
    except Exception:
        return False
    else:
        return True
def supress_noisy_logs():
    """Set some custom log levels on some sub logs"""
    for name, level in NOISY_LOGS.items():
        logger = logging.getLogger(name)
        logger.setLevel(level)
def configure_warnings(enable):
    # never propogate warnings to root
    warnings = logging.getLogger('py.warnings')
    warnings.propagate = False
    if enable:
        warnings.addHandler(logging.StreamHandler())
def configure_test_logging(handler=None):
    """Add a handler (defaults to NullHandler) to root logger.
    Prevents unconfigured logging from erroring, and swallows all logging,
    which is usually what you want for unit tests.  Unit test fixtures can
    still add their own loggers to assert against log messages if needed.
    """
    set_logger_class()
    if handler is None:
        handler = logging.NullHandler()
    add_talisker_handler(logging.NOTSET, handler)
    configure_warnings(True)
def enable_debug_log_stderr():
    """Enables debug logging on stderr
    Checks for devel mode."""
    logger = logging.getLogger(__name__)
    logger.warning('setting stderr logging to DEBUG')
    get_talisker_handler().setLevel(logging.DEBUG)
class StructuredLogger(logging.Logger):
    """A logger that handles passing 'extra' arguments to all logging calls.
    Supports 3 sources of extra structured data:
    1) global extra, designed to be set once at process start/
    2) context extra, designed to be set per request or job, can cleaned up
       afterwards.
    3) per call extra, passed by the log call, as per normal logging
       e.g. log.info('...', extra={...})
    """
    # sadly, we must subclass and override, rather that use the new
    # setLogRecordFactory() in 3.2+, as that does not pass the extra args
    # through. Also, we need to support python 2.
    def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
                   func=None, extra=None, sinfo=None):
        # at this point we have 3 possible sources of extra kwargs
        # - log call: extra
        # - context : local_context.flat
        # - global  : logging_globals['extra']
        #
        # In case of collisions, we append _ to the end of the name, so no data
        # is lost. The global ones are more important, so take priority - the
        # user supplied keys are the ones renamed if needed
        # Also, the ordering is specific - more specific tags first
        trailer = None
        structured = OrderedDict()
        try:
            if ContextId.get(None) is None:
                context_extra = {}
                request_id = None
            else:
                context_extra = logging_context.flat
                request_id = Context.request_id
            global_extra = logging_globals.get('extra', {})
            if extra:
                trailer = extra.pop('trailer', None)
                for k, v in extra.items():
                    if k in context_extra or k in global_extra:
                        k = k + '_'
                    structured[k] = v
            for k, v in context_extra.items():
                if k in global_extra:
                    k = k + '_'
                structured[k] = v
            structured.update(global_extra)
            if request_id:
                structured['request_id'] = request_id
        except Exception:
            # ensure unexpected error doesn't break logging completely
            structured = extra
        kwargs = dict(func=func, extra=structured, sinfo=sinfo)
        # python 2 doesn't support sinfo parameter


Please complete the code given below. 
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Mobiles;
using Server.Targeting;
using Server.ContextMenus;
using Server.Regions;
using Server.Network;
using System.Collections.Generic;
using Server.Items;
using Server.Targets;
namespace Server.Items
{
	public class SpellweavingTrainer : Item
	{
		public override string DefaultName
		{
			get { return "Spellweaving Trainer [100GP]"; }
		}
		[Constructable]
		public SpellweavingTrainer() : base( 0x1F1C )
		{
			Weight = 1.0;
            Movable = false;
		}
		public SpellweavingTrainer( Serial serial ) : base( serial )
		{
		}
        public override void OnDoubleClick(Mobile m)
        {
            if (m.Skills.Spellweaving.Base <= 19.9)
            {
                if (m.Mana >= 4)
                {
                    if (m.SkillsTotal >= m.SkillsCap)
                    {
                        int toGain = 1;
                        Skills skills = m.Skills;
                        for (int i = 0; i < skills.Length; ++i)
                        {
                            Skill toLower = skills[i];
                            if (toLower != m.Skills.Spellweaving && toLower.Lock == SkillLock.Down && toLower.BaseFixedPoint >= toGain)
                            {
                                toLower.BaseFixedPoint -= toGain;
                                break;
                            }
                        }
                    }
                    if (m.SkillsTotal < m.SkillsCap)
                    {
                        if (m.Backpack.ConsumeTotal(typeof(Gold), 100))
                        {
                            if (m.Skills.Spellweaving.Base < m.Skills.Spellweaving.Cap)
                            {
                                m.Skills.Spellweaving.BaseFixedPoint += 1;
                                m.Mana -= 4;
                            }
                            else
                            {
                                m.SendMessage("You have reached the skill cap for that skill");
                            }
                        }
                        else
                        m.SendMessage("You need 100gp in your pack to use this stone.");
                    }
                    else
                    {
                        m.SendMessage("you have reached your total skills cap. Set a skill to lower to continue using me");
                    }
                }
            }
            if (m.Skills.Spellweaving.Base <= 39.9 && m.Skills.Spellweaving.Base >= 20)
            {
                if (m.Mana >= 5)
                {
                    if (m.SkillsTotal >= m.SkillsCap)
                    {
                        int toGain = 1;
                        Skills skills = m.Skills;
                        for (int i = 0; i < skills.Length; ++i)
                        {
                            Skill toLower = skills[i];
                            if (toLower != m.Skills.Spellweaving && toLower.Lock == SkillLock.Down && toLower.BaseFixedPoint >= toGain)
                            {
                                toLower.BaseFixedPoint -= toGain;
                                break;
                            }
                        }
                    }
                    if (m.SkillsTotal < m.SkillsCap)
                    {
                        if (m.Backpack.ConsumeTotal(typeof(Gold), 100))
                        {
                            if (m.Skills.Spellweaving.Base < m.Skills.Spellweaving.Cap)
                            {
                                m.Skills.Spellweaving.BaseFixedPoint += 1;
                                m.Mana -= 5;
                            }
                            else
                            {
                                m.SendMessage("You have reached the skill cap for that skill");
                            }
                        }
                        else
                        m.SendMessage("You need 100gp in your pack to use this stone.");
                    }
                    else
                    {
                        m.SendMessage("you have reached your total skills cap. Set a skill to lower to continue using me");
                    }
                }
                else
                {
                    m.SendMessage("You need 5 mana to use this item at your skill level.");
                }
            }
            if (m.Skills.Spellweaving.Base <= 59.9 && m.Skills.Spellweaving.Base >= 40)
            {
                if (m.Mana >= 10)
                {
                    if (m.SkillsTotal >= m.SkillsCap)
                    {
                        int toGain = 1;
                        Skills skills = m.Skills;
                        for (int i = 0; i < skills.Length; ++i)
                        {
                            Skill toLower = skills[i];
                            if (toLower != m.Skills.Spellweaving && toLower.Lock == SkillLock.Down && toLower.BaseFixedPoint >= toGain)
                            {
                                toLower.BaseFixedPoint -= toGain;
                                break;
                            }
                        }
                    }
                    if (m.SkillsTotal < m.SkillsCap)
                    {
                        if (m.Backpack.ConsumeTotal(typeof(Gold), 100))
                        {
                            if (m.Skills.Spellweaving.Base < m.Skills.Spellweaving.Cap)
                            {
                                m.Skills.Spellweaving.BaseFixedPoint += 1;
                                m.Mana -= 10;
                            }
                            else
                            {
                                m.SendMessage("You have reached the skill cap for that skill");
                            }
                        }
                        else
                        m.SendMessage("You need 100gp in your pack to use this stone.");
                    }
                    else
                    {
                        m.SendMessage("you have reached your total skills cap. Set a skill to lower to continue using me");
                    }
                }
                else
                {
                    m.SendMessage("You need 10 mana to use this item at your skill level.");
                }
            }
            if (m.Skills.Spellweaving.Base <= 79.9 && m.Skills.Spellweaving.Base >= 60)
            {
                if (m.Mana >= 20)
                {
                    if (m.SkillsTotal >= m.SkillsCap)
                    {
                        int toGain = 1;
                        Skills skills = m.Skills;
                        for (int i = 0; i < skills.Length; ++i)
                        {
                            Skill toLower = skills[i];
                            if (toLower != m.Skills.Spellweaving && toLower.Lock == SkillLock.Down && toLower.BaseFixedPoint >= toGain)
                            {
                                toLower.BaseFixedPoint -= toGain;
                                break;
                            }
                        }
                    }
                    if (m.SkillsTotal < m.SkillsCap)
                    {
                        if (m.Backpack.ConsumeTotal(typeof(Gold), 100))
                        {
                            if (m.Skills.Spellweaving.Base < m.Skills.Spellweaving.Cap)
                            {
                                m.Skills.Spellweaving.BaseFixedPoint += 1;


Please complete the code given below. 
"""
Step definitions for working with Django models.
"""
from datetime import datetime
import re
from django.core.management import call_command
from django.core.management.color import no_style
from django.db import connection
from django.db.models.loading import get_models
from django.utils.functional import curry
from functools import wraps
from lettuce import step
STEP_PREFIX = r'(?:Given|And|Then|When) '
def _models_generator():
    """
    Build a hash of model verbose names to models
    """
    for model in get_models():
        yield (unicode(model._meta.verbose_name), model)
        yield (unicode(model._meta.verbose_name_plural), model)
MODELS = dict(_models_generator())
_WRITE_MODEL = {}
def creates_models(model):
    """
    Register a model-specific creation function. Wrapper around writes_models
    that removes the field parameter (always a create operation).
    """
    def decorated(func):
        @wraps(func)
        @writes_models(model)
        def wrapped(data, field):
            if field:
                raise NotImplementedError(
                    "Must use the writes_models decorator to update models")
            return func(data)
    return decorated
def writes_models(model):
    """
    Register a model-specific create and update function.
    """
    def decorated(func):
        """
        Decorator for the creation function.
        """
        _WRITE_MODEL[model] = func
        return func
    return decorated
_MODEL_EXISTS = {}
def checks_existence(model):
    """
    Register a model-specific existence check function.
    """
    def decorated(func):
        """
        Decorator for the existence function.
        """
        _MODEL_EXISTS[model] = func
        return func
    return decorated
def hash_data(hash_):
    """
    Convert strings from a Lettuce hash to appropriate types
    """
    res = {}
    for key, value in hash_.items():
        if type(value) in (str, unicode):
            if value == "true":
                value = True
            elif value == "false":
                value = False
            elif value == "null":
                value = None
            elif value.isdigit() and not re.match("^0[0-9]+", value):
                value = int(value)
            elif re.match(r'^\d{4}-\d{2}-\d{2}$', value):
                value = datetime.strptime(value, "%Y-%m-%d")
        res[key] = value
    return res
def hashes_data(step):
    """
    Convert strings from step hashes to appropriate types
    """
    return [hash_data(hash_) for hash_ in step.hashes]
def get_model(model):
    """
    Convert a model's verbose name to the model class. This allows us to
    use the models verbose name in steps.
    """
    name = model.lower()
    model = MODELS.get(model, None)
    assert model, "Could not locate model by name '%s'" % name
    return model
def reset_sequence(model):
    """
    Reset the ID sequence for a model.
    """
    sql = connection.ops.sequence_reset_sql(no_style(), [model])
    for cmd in sql:
        connection.cursor().execute(cmd)
def create_models(model, data):
    """
    Create models for each data hash. Wrapper around write_models.
    """
    return write_models(model, data, None)
def write_models(model, data, field=None):
    """
    Create or update models for each data hash. If field is present, it is the
    field that is used to get the existing models out of the database to update
    them; otherwise, new models are created.
    """
    if hasattr(data, 'hashes'):
        data = hashes_data(data)
    written = []
    for hash_ in data:
        if field:
            if field not in hash_:
                raise KeyError(("The \"%s\" field is required for all update "
                                "operations") % field)
            model_kwargs = {field: hash_[field]}
            model_obj = model.objects.get(**model_kwargs)
            for to_set, val in hash_.items():
                setattr(model_obj, to_set, val)
            model_obj.save()
        else:
            model_obj = model.objects.create(**hash_)
        written.append(model_obj)
    reset_sequence(model)
    return written
def _dump_model(model, attrs=None):
    """
    Dump the model fields for debugging.
    """
    for field in model._meta.fields:
        print '%s=%s,' % (field.name, str(getattr(model, field.name))),
    if attrs is not None:
        for attr in attrs:
            print '%s=%s,' % (attr, str(getattr(model, attr))),
    for field in model._meta.many_to_many:
        vals = getattr(model, field.name)
        print '%s=%s (%i),' % (
            field.name,
            ', '.join(map(str, vals.all())),
            vals.count()),
    print
def models_exist(model, data, queryset=None):
    """
    Check whether the models defined by @data exist in the @queryset.
    """
    if hasattr(data, 'hashes'):
        data = hashes_data(data)
    if not queryset:
        queryset = model.objects
    failed = 0
    try:
        for hash_ in data:
            fields = {}
            extra_attrs = {}


Please complete the code given below. 
## This file is part of Invenio.
## Copyright (C) 2009, 2010, 2011 CERN.
##
## Invenio is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## Invenio is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
# pylint: disable=C0103
"""Invenio BibEdit Administrator Interface."""
__revision__ = "$Id"
__lastupdated__ = """$Date: 2008/08/12 09:26:46 $"""
import cProfile
import cStringIO
import pstats
from invenio.jsonutils import json, json_unicode_to_utf8
from invenio.access_control_engine import acc_authorize_action
from invenio.bibedit_engine import (perform_request_ajax,
                                    perform_request_init,
                                    perform_request_newticket,
                                    perform_request_compare,
                                    perform_request_init_template_interface,
                                    perform_request_ajax_template_interface)
from invenio.bibedit_utils import user_can_edit_record_collection
from invenio.config import CFG_SITE_LANG, CFG_SITE_SECURE_URL, CFG_SITE_RECORD
from invenio.messages import gettext_set_language
from invenio.urlutils import redirect_to_url
from invenio.webinterface_handler import WebInterfaceDirectory, wash_urlargd
from invenio.webpage import page
from invenio.webuser import collect_user_info, getUid, page_not_authorized
navtrail = (' <a class="navtrail" href=\"%s/help/admin\">Admin Area</a> '
            ) % CFG_SITE_SECURE_URL
navtrail_bibedit = (' <a class="navtrail" href=\"%s/help/admin\">Admin Area</a> ' + \
                    ' &gt; <a class="navtrail" href=\"%s/%s/edit\">Record Editor</a>'
            ) % (CFG_SITE_SECURE_URL, CFG_SITE_SECURE_URL, CFG_SITE_RECORD)
def wrap_json_req_profiler(func):
    def json_req_profiler(self, req, form):
        if "ajaxProfile" in form:
            profiler = cProfile.Profile()
            return_val = profiler.runcall(func, self, req, form)
            results = cStringIO.StringIO()
            stats = pstats.Stats(profiler, stream=results)
            stats.sort_stats('cumulative')
            stats.print_stats(100)
            json_in = json.loads(str(form['jsondata']))
            # Deunicode all strings (Invenio doesn't have unicode
            # support).
            json_in = json_unicode_to_utf8(json_in)
            json_data = json.loads(return_val)
            json_data.update({"profilerStats": "<pre style='overflow: scroll'>" + json_in['requestType'] + results.getvalue() + "</pre>"})
            return json.dumps(json_data)
        else:
            return func(self, req, form)
    return json_req_profiler
class WebInterfaceEditPages(WebInterfaceDirectory):
    """Defines the set of /edit pages."""
    _exports = ['', 'new_ticket', 'compare_revisions', 'templates']
    def __init__(self, recid=None):
        """Initialize."""
        self.recid = recid
    @wrap_json_req_profiler
    def index(self, req, form):
        """Handle all BibEdit requests.
        The responsibilities of this functions is:
        * JSON decoding and encoding.
        * Redirection, if necessary.
        * Authorization.
        * Calling the appropriate function from the engine.
        """
        uid = getUid(req)
        argd = wash_urlargd(form, {'ln': (str, CFG_SITE_LANG)})
        # If it is an Ajax request, extract any JSON data.
        ajax_request, recid = False, None
        if form.has_key('jsondata'):
            json_data = json.loads(str(form['jsondata']))
            # Deunicode all strings (Invenio doesn't have unicode
            # support).
            json_data = json_unicode_to_utf8(json_data)
            ajax_request = True
            if json_data.has_key('recID'):
                recid = json_data['recID']
            json_response = {'resultCode': 0, 'ID': json_data['ID']}
        # Authorization.
        user_info = collect_user_info(req)
        if user_info['email'] == 'guest':
            # User is not logged in.
            if not ajax_request:
                # Do not display the introductory recID selection box to guest
                # users (as it used to be with v0.99.0):
                dummy_auth_code, auth_message = acc_authorize_action(req,
                                                               'runbibedit')
                referer = '/edit/'
                if self.recid:
                    referer = '/%s/%s/edit/' % (CFG_SITE_RECORD, self.recid)
                return page_not_authorized(req=req, referer=referer,
                                           text=auth_message, navtrail=navtrail)
            else:
                # Session has most likely timed out.
                json_response.update({'resultCode': 100})
                return json.dumps(json_response)
        elif self.recid:
            # Handle redirects from /record/<record id>/edit
            # generic URL.
            redirect_to_url(req, '%s/%s/edit/#state=edit&recid=%s&recrev=%s' % (
                    CFG_SITE_SECURE_URL, CFG_SITE_RECORD, self.recid, ""))
        elif recid is not None:
            json_response.update({'recID': recid})
            if json_data['requestType'] == "getRecord":
                # Authorize access to record.
                if not user_can_edit_record_collection(req, recid):
                    json_response.update({'resultCode': 101})
                    return json.dumps(json_response)
        # Handle request.
        if not ajax_request:
            # Show BibEdit start page.
            body, errors, warnings = perform_request_init(uid, argd['ln'], req, __lastupdated__)
            title = 'Record Editor'
            return page(title       = title,
                        body        = body,
                        errors      = errors,
                        warnings    = warnings,
                        uid         = uid,
                        language    = argd['ln'],
                        navtrail    = navtrail,
                        lastupdated = __lastupdated__,
                        req         = req,
                        body_css_classes = ['bibedit'])
        else:
            # Handle AJAX request.
            json_response.update(perform_request_ajax(req, recid, uid,
                                                      json_data))
            return json.dumps(json_response)
    def compare_revisions(self, req, form):
        """Handle the compare revisions request"""
        argd = wash_urlargd(form, { \
                'ln': (str, CFG_SITE_LANG), \
                'rev1' : (str, ''), \
                'rev2' : (str, ''), \
                'recid': (int, 0)})
        ln = argd['ln']
        uid = getUid(req)
        _ = gettext_set_language(ln)
        # Checking if currently logged user has permission to perform this request
        auth_code, auth_message = acc_authorize_action(req, 'runbibedit')
        if auth_code != 0:
            return page_not_authorized(req=req, referer="/edit",
                                       text=auth_message, navtrail=navtrail)
        recid = argd['recid']
        rev1 = argd['rev1']
        rev2 = argd['rev2']
        ln = argd['ln']
        body, errors, warnings = perform_request_compare(ln, recid, rev1, rev2)
        return page(title = _("Comparing two record revisions"),
                    body =  body,
                    errors = errors,
                    warnings = warnings,
                    uid = uid,
                    language = ln,
                    navtrail    = navtrail,
                    lastupdated = __lastupdated__,
                    req         = req,
                    body_css_classes = ['bibedit'])
    def new_ticket(self, req, form):
        """handle a edit/new_ticket request"""
        argd = wash_urlargd(form, {'ln': (str, CFG_SITE_LANG), 'recid': (int, 0)})
        ln = argd['ln']
        _ = gettext_set_language(ln)
        auth_code, auth_message = acc_authorize_action(req, 'runbibedit')
        if auth_code != 0:


Please complete the code given below. 
# Copyright (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
# Copyright 2015 Abhijit Menon-Sen <ams@2ndQuadrant.com>
# Copyright 2017 Toshio Kuratomi <tkuratomi@ansible.com>
# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
    connection: ssh
    short_description: connect via ssh client binary
    description:
        - This connection plugin allows ansible to communicate to the target machines via normal ssh command line.
        - Ansible does not expose a channel to allow communication between the user and the ssh process to accept
          a password manually to decrypt an ssh key when using this connection plugin (which is the default). The
          use of ``ssh-agent`` is highly recommended.
    author: ansible (@core)
    version_added: historical
    options:
      host:
          description: Hostname/ip to connect to.
          default: inventory_hostname
          vars:
               - name: ansible_host
               - name: ansible_ssh_host
      host_key_checking:
          description: Determines if ssh should check host keys
          type: boolean
          ini:
              - section: defaults
                key: 'host_key_checking'
              - section: ssh_connection
                key: 'host_key_checking'
                version_added: '2.5'
          env:
              - name: ANSIBLE_HOST_KEY_CHECKING
              - name: ANSIBLE_SSH_HOST_KEY_CHECKING
                version_added: '2.5'
          vars:
              - name: ansible_host_key_checking
                version_added: '2.5'
              - name: ansible_ssh_host_key_checking
                version_added: '2.5'
      password:
          description: Authentication password for the C(remote_user). Can be supplied as CLI option.
          vars:
              - name: ansible_password
              - name: ansible_ssh_pass
              - name: ansible_ssh_password
      ssh_args:
          description: Arguments to pass to all ssh cli tools
          default: '-C -o ControlMaster=auto -o ControlPersist=60s'
          ini:
              - section: 'ssh_connection'
                key: 'ssh_args'
          env:
              - name: ANSIBLE_SSH_ARGS
          vars:
              - name: ansible_ssh_args
                version_added: '2.7'
      ssh_common_args:
          description: Common extra args for all ssh CLI tools
          ini:
              - section: 'ssh_connection'
                key: 'ssh_common_args'
                version_added: '2.7'
          env:
              - name: ANSIBLE_SSH_COMMON_ARGS
                version_added: '2.7'
          vars:
              - name: ansible_ssh_common_args
      ssh_executable:
          default: ssh
          description:
            - This defines the location of the ssh binary. It defaults to ``ssh`` which will use the first ssh binary available in $PATH.
            - This option is usually not required, it might be useful when access to system ssh is restricted,
              or when using ssh wrappers to connect to remote hosts.
          env: [{name: ANSIBLE_SSH_EXECUTABLE}]
          ini:
          - {key: ssh_executable, section: ssh_connection}
          #const: ANSIBLE_SSH_EXECUTABLE
          version_added: "2.2"
          vars:
              - name: ansible_ssh_executable
                version_added: '2.7'
      sftp_executable:
          default: sftp
          description:
            - This defines the location of the sftp binary. It defaults to ``sftp`` which will use the first binary available in $PATH.
          env: [{name: ANSIBLE_SFTP_EXECUTABLE}]
          ini:
          - {key: sftp_executable, section: ssh_connection}
          version_added: "2.6"
          vars:
              - name: ansible_sftp_executable
                version_added: '2.7'
      scp_executable:
          default: scp
          description:
            - This defines the location of the scp binary. It defaults to `scp` which will use the first binary available in $PATH.
          env: [{name: ANSIBLE_SCP_EXECUTABLE}]
          ini:
          - {key: scp_executable, section: ssh_connection}
          version_added: "2.6"
          vars:
              - name: ansible_scp_executable
                version_added: '2.7'
      scp_extra_args:
          description: Extra exclusive to the ``scp`` CLI
          vars:
              - name: ansible_scp_extra_args
          env:
            - name: ANSIBLE_SCP_EXTRA_ARGS
              version_added: '2.7'
          ini:
            - key: scp_extra_args
              section: ssh_connection
              version_added: '2.7'
      sftp_extra_args:
          description: Extra exclusive to the ``sftp`` CLI
          vars:
              - name: ansible_sftp_extra_args
          env:
            - name: ANSIBLE_SFTP_EXTRA_ARGS
              version_added: '2.7'
          ini:
            - key: sftp_extra_args
              section: ssh_connection
              version_added: '2.7'
      ssh_extra_args:
          description: Extra exclusive to the 'ssh' CLI
          vars:
              - name: ansible_ssh_extra_args
          env:
            - name: ANSIBLE_SSH_EXTRA_ARGS
              version_added: '2.7'
          ini:
            - key: ssh_extra_args
              section: ssh_connection
              version_added: '2.7'
      retries:
          # constant: ANSIBLE_SSH_RETRIES
          description: Number of attempts to connect.
          default: 3
          type: integer
          env:
            - name: ANSIBLE_SSH_RETRIES
          ini:
            - section: connection
              key: retries
            - section: ssh_connection
              key: retries
          vars:
            - name: ansible_ssh_retries
              version_added: '2.7'
      port:
          description: Remote port to connect to.
          type: int
          default: 22
          ini:
            - section: defaults
              key: remote_port
          env:
            - name: ANSIBLE_REMOTE_PORT
          vars:
            - name: ansible_port
            - name: ansible_ssh_port
      remote_user:
          description:
              - User name with which to login to the remote server, normally set by the remote_user keyword.
              - If no user is supplied, Ansible will let the ssh client binary choose the user as it normally
          ini:
            - section: defaults
              key: remote_user
          env:
            - name: ANSIBLE_REMOTE_USER
          vars:
            - name: ansible_user
            - name: ansible_ssh_user
      pipelining:
          default: ANSIBLE_PIPELINING
          description:
            - Pipelining reduces the number of SSH operations required to execute a module on the remote server,
              by executing many Ansible modules without actual file transfer.
            - This can result in a very significant performance improvement when enabled.
            - However this conflicts with privilege escalation (become).
              For example, when using sudo operations you must first disable 'requiretty' in the sudoers file for the target hosts,
              which is why this feature is disabled by default.
          env:
            - name: ANSIBLE_PIPELINING
            #- name: ANSIBLE_SSH_PIPELINING
          ini:
            - section: defaults
              key: pipelining
            #- section: ssh_connection
            #  key: pipelining
          type: boolean
          vars:
            - name: ansible_pipelining
            - name: ansible_ssh_pipelining
      private_key_file:
          description:
              - Path to private key file to use for authentication
          ini:
            - section: defaults
              key: private_key_file
          env:
            - name: ANSIBLE_PRIVATE_KEY_FILE
          vars:
            - name: ansible_private_key_file
            - name: ansible_ssh_private_key_file
      control_path:
        description:
          - This is the location to save ssh's ControlPath sockets, it uses ssh's variable substitution.
          - Since 2.3, if null, ansible will generate a unique hash. Use `%(directory)s` to indicate where to use the control dir path setting.
        env:
          - name: ANSIBLE_SSH_CONTROL_PATH
        ini:
          - key: control_path
            section: ssh_connection
        vars:
          - name: ansible_control_path
            version_added: '2.7'
      control_path_dir:
        default: ~/.ansible/cp
        description:
          - This sets the directory to use for ssh control path if the control path setting is null.
          - Also, provides the `%(directory)s` variable for the control path setting.
        env:
          - name: ANSIBLE_SSH_CONTROL_PATH_DIR
        ini:
          - section: ssh_connection
            key: control_path_dir
        vars:
          - name: ansible_control_path_dir
            version_added: '2.7'
      sftp_batch_mode:
        default: 'yes'
        description: 'TODO: write it'
        env: [{name: ANSIBLE_SFTP_BATCH_MODE}]
        ini:
        - {key: sftp_batch_mode, section: ssh_connection}
        type: bool
        vars:
          - name: ansible_sftp_batch_mode
            version_added: '2.7'
      scp_if_ssh:
        default: smart
        description:
          - "Prefered method to use when transfering files over ssh"
          - When set to smart, Ansible will try them until one succeeds or they all fail
          - If set to True, it will force 'scp', if False it will use 'sftp'
        env: [{name: ANSIBLE_SCP_IF_SSH}]
        ini:
        - {key: scp_if_ssh, section: ssh_connection}
        vars:
          - name: ansible_scp_if_ssh
            version_added: '2.7'
      use_tty:
        version_added: '2.5'
        default: 'yes'
        description: add -tt to ssh commands to force tty allocation
        env: [{name: ANSIBLE_SSH_USETTY}]
        ini:


Please complete the code given below. 
//#############################################################################
//#                                                                           #
//#  Copyright (C) <2014>  <IMS MAXIMS>                                       #
//#                                                                           #
//#  This program is free software: you can redistribute it and/or modify     #
//#  it under the terms of the GNU Affero General Public License as           #
//#  published by the Free Software Foundation, either version 3 of the       #
//#  License, or (at your option) any later version.                          # 
//#                                                                           #
//#  This program is distributed in the hope that it will be useful,          #
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of           #
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            #
//#  GNU Affero General Public License for more details.                      #
//#                                                                           #
//#  You should have received a copy of the GNU Affero General Public License #
//#  along with this program.  If not, see <http://www.gnu.org/licenses/>.    #
//#                                                                           #
//#############################################################################
//#EOH
// Template ver. 1.0.2 - Last modified on 08/03/2004 10:42 by Marius Mihalec
package ims.dto.client;
public final class Wardlist
{
	private WardlistFilter lastGetFilter = null;
	private final String serviceName = "WARDLIST";
	private boolean listInProgress = false;
	/**
	 * Represents the Data Transfer Object Connection used for this client object.
	 */ 
	public ims.dto.Connection Connection = null;
	/**
	 * Represents the filter used by the current Data Transfer Object.
	 */ 
	public WardlistFilter Filter = new WardlistFilter();			
	/**
	 * Contains the data records for the current Data Transfer Object
	 */ 
	public WardlistCollection DataCollection = new WardlistCollection();
	/**
	 * Creates a new Wardlist Data Transfer Object.
	 */ 
	public Wardlist(ims.dto.Connection connection) throws ims.dto.Exception
	{	
		if(connection == null)
			throw new ims.dto.Exception("Invalid Data Transfer Object Connection");
		this.Connection = connection;
	}
	/**
	 * Creates a new copy of the current Data Transfer Object
	 */
	public Wardlist cloneObject() throws ims.dto.Exception
	{
		Wardlist cloneObject = new Wardlist(Connection);
			
		if(Filter != null)
			cloneObject.Filter = Filter.cloneObject();			
					
		if(lastGetFilter != null)
			cloneObject.lastGetFilter = lastGetFilter.cloneObject();
		else
			cloneObject.lastGetFilter = null;
				
		for(int x = 0; x < DataCollection.count(); x++)
		{
			int index = cloneObject.DataCollection.add();
			
			cloneObject.DataCollection.get(index).Rsno = DataCollection.get(x).Rsno;
			cloneObject.DataCollection.get(index).Hpcd = DataCollection.get(x).Hpcd;
			cloneObject.DataCollection.get(index).Site = DataCollection.get(x).Site;
			cloneObject.DataCollection.get(index).Name = DataCollection.get(x).Name;
			cloneObject.DataCollection.get(index).Code = DataCollection.get(x).Code;
			cloneObject.DataCollection.get(index).Stat = DataCollection.get(x).Stat;
			cloneObject.DataCollection.get(index).At01 = DataCollection.get(x).At01;
			cloneObject.DataCollection.get(index).Maxno = DataCollection.get(x).Maxno;
			cloneObject.DataCollection.get(index).Allstat = DataCollection.get(x).Allstat;
			cloneObject.DataCollection.get(index).__orderby = DataCollection.get(x).__orderby;
							
			
		}
		
		return cloneObject;
	}		
	/**
	 * Returns the number of records using the specified filter. This method always returns a non null result. The ID field holds the count result (when greater or equal to zero) or the error number (when less than zero).
	 */
	public ims.dto.Result count()
	{
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.Count");
			
		int result = Connection.count(serviceName, encodeNASFilter());
		if(result >= 0)
			return new ims.dto.Result(result, "No error detected. The count result is held in the ID field", "DTO.Client.Wardlist.Count");
				
		return Connection.getLastError();				
	}		
	/**
	 * Returns the list of records using the specified filter. Use maxRecords to limit the number of records returned. If the result returned is not null an error occured.
	 */
	public ims.dto.Result list(int maxRecords)
	{
		if(maxRecords <= 0)
			return list();		
				
		return list(false, maxRecords);
	}	
	/**
	* Returns the list of records using the specified filter. If the result returned is not null an error occured.
	*/
	public ims.dto.Result list()
	{	
		return list(true, 0);
	}				
	/**
	* Returns one record using the specified filter. If the result returned is not null an error occured.
	*/
	public ims.dto.Result get()
	{	
		DataCollection.clear();
			
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.Get");
			
		ims.dto.Result result = Connection.get(serviceName, encodeNASFilter());
		if(result != null)
			return result;
			
		lastGetFilter = Filter.cloneObject();						
		decodeNASMessageWithRepeatingGroups();		
			
		return null;
	}	
	/**
	* Returns one record using the specified filter. If the result returned is not null an error occured.
	*/
	public ims.dto.Result getLast()
	{	
		DataCollection.clear();
			
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.Get");
			
		ims.dto.Result result = Connection.getLast(serviceName, encodeNASFilter());
		if(result != null)
			return result;
			
		lastGetFilter = Filter.cloneObject();						
		decodeNASMessageWithRepeatingGroups();	
			
		return null;
	}					
	/**
	* Performs data validation prior to update. If the result returned is not null an error occured.
	*/
	public ims.dto.Result getForUpdate()
	{						
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.GetForUpdate");
							
		if(lastGetFilter == null)	
			return new ims.dto.Result("Last get method failed or not called", "DTO.Client.Wardlist.GetForUpdate");
			
		ims.dto.Result result = Connection.getForUpdate(serviceName, encodeNASFilter(lastGetFilter));
		if(result != null)
			return result;
			
		if(Connection.countResponseItems(Connection.getValueAt(6)) == 0)
			return null;
			
		DataCollection.clear();	
		decodeNASMessageWithRepeatingGroups();
				
		return new ims.dto.Result("The data was changed by another user", "DTO.Client.Wardlist.GetForUpdate");
	}		
	/**
	* Inserts a new record. This method always returns a non null result. The ID field holds the Unique ID for the inserted record (when greater than zero) or the error number (when less than zero). If the ID is zero, the record was inserted but the server did not returned the Unique ID.
	*/
	public ims.dto.Result insert()
	{
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.Insert");
					
		if(DataCollection.count() == 0)
			return new ims.dto.Result("No data to insert", "DTO.Client.Wardlist.Insert");
			
		if(DataCollection.count() > 1)
			return new ims.dto.Result("Multiple object insert not allowed", "DTO.Client.Wardlist.Insert");
			
		ims.dto.Result result = Connection.insert(serviceName, encodeNASMessage());
		if(result != null)
			return result;
					
		int recordID = 0;
					
		try
		{
			recordID = new Integer(Connection.getValueAt(2)).intValue();
		}
		catch(NumberFormatException ex)
		{
			return new ims.dto.Result("Invalid record ID returned", "DTO.Client.Wardlist.Insert");
		}
		
		return new ims.dto.Result(recordID, "No error. The ID of the new record is in the ID field", "DTO.Client.Wardlist.Insert");
	}
	/**
	 * Executes a specific action. This method always returns a non null result.
	 */
	public ims.dto.Result executeAction(String action)
	{
		if(action.length() == 0)
			return new ims.dto.Result("Invalid action name", "DTO.Client.Wardlist.ExecuteAction");
			
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.ExecuteAction");
		
		if(DataCollection.count() == 0)
			return new ims.dto.Result("Data container is empty", "DTO.Client.Wardlist.ExecuteAction");
			
		if(DataCollection.count() > 1)
			return new ims.dto.Result("Multiple objects are not allowed", "DTO.Client.Wardlist.ExecuteAction");
			
		ims.dto.Result result = Connection.executeAction(serviceName, encodeNASMessage(), action);
		if(result != null)
			return result;
			
		try
		{
			return new ims.dto.Result(new Integer(Connection.getValueAt(2)).intValue(), "No error", "DTO.Client.Wardlist.ExecuteAction");	
		}
		catch(NumberFormatException ex)
		{
			return new ims.dto.Result("Invalid server response", "DTO.Client.Wardlist.ExecuteAction");
		}
	}
	/**
	 * Transfers a record. If the result returned is not null an error occured.
	 */
	public ims.dto.Result transferData(String action)
	{
		if(action.length() == 0)
			return new ims.dto.Result("Invalid action name", "DTO.Client.Wardlist.TransferData");
			
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.TransferData");
		
		if(DataCollection.count() == 0)
			return new ims.dto.Result("No data to transfer", "DTO.Client.Wardlist.TransferData");
			
		if(DataCollection.count() > 1)
			return new ims.dto.Result("Multiple objects not allowed", "DTO.Client.Wardlist.TransferData");
			
		ims.dto.Result result = Connection.transferData(serviceName, encodeNASMessage(), action.toUpperCase());
		if(result != null)
			return result;
		
		DataCollection.clear();
		decodeNASMessageWithRepeatingGroups();	
		
		return null;
	}
	/**
	 * Updates a record. If the result returned is not null an error occured.
	 */
	public ims.dto.Result update()
	{			
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.Update");
				
		if(DataCollection.count() == 0)
			return new ims.dto.Result("No data to update", "DTO.Client.Wardlist.Update");	
			
		if(DataCollection.count() > 1)
			return new ims.dto.Result("Multiple object update not allowed", "DTO.Client.Wardlist.Update");
			
		return Connection.update(serviceName, encodeNASMessage());
	}
			
	private ims.dto.Result stopList()
	{
		if(!listInProgress)
			return new ims.dto.Result("No active list running", "DTO.Client.Wardlist.StopList");
				
		listInProgress = false;				
		return null;
	}
	
	private ims.dto.Result nextList()
	{				
		ims.dto.Result result = Connection.nextList(serviceName);
		if(result != null)
			return result;
					
		decodeNASMessage();		
		return null;
	}
		
	private boolean canContinueToList(boolean loadAllRecords, int maxRecords)
	{
		if(!listInProgress)
			return false;				
		if(loadAllRecords)
			return true;			
		return DataCollection.count() < maxRecords;
	}
	
	private ims.dto.Result list(boolean loadAllRecords, int maxRecords)
	{	
		DataCollection.clear();
			
		ims.dto.Result reLoginResult = Connection.reLogin();
		if(reLoginResult != null)
			return new ims.dto.Result(reLoginResult.getMessage(), "DTO.Client.Wardlist.List");
							
		listInProgress = true;	
		ims.dto.Result result = Connection.list(serviceName, encodeNASFilter());
		if(result != null)
		{
			listInProgress = false;
			if(result.getId() == -2) // NAS list empty
				return null;
			return result;
		}
					
		if(decodeNASMessage() == 0)
		{
			listInProgress = false;
			return null;
		}
						
		ims.dto.Result execResult = null;
		while(execResult == null && canContinueToList(loadAllRecords, maxRecords))
			execResult = nextList();
						
		if(execResult != null)
		{
			if(execResult.getId() != -3) 
			{
				listInProgress = false;
				return execResult;
			}
		}
		else // NAS next list empty
		{
			listInProgress = false;
			return null;
		}				
					
		if(!loadAllRecords || !listInProgress)
		{
			listInProgress = false;
			return Connection.stopList(serviceName);
		}
		
		listInProgress = false;
		return null;
	}	
	private String encodeNASFilter()
	{
		return encodeNASFilter(Filter);
	}
	private String encodeNASFilter(WardlistFilter filter)
	{
		if(filter == null)
			return "";
			
		String filterString = "";
		
		if(Filter.Rsno != null && filter.Rsno.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "RSNO" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.Rsno;
		}
		
		if(Filter.Hpcd != null && filter.Hpcd.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "HPCD" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.Hpcd;
		}
		
		if(Filter.Site != null && filter.Site.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "SITE" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.Site;
		}
		
		if(Filter.Name != null && filter.Name.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "NAME" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.Name;
		}
		
		if(Filter.Code != null && filter.Code.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "CODE" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.Code;
		}
		
		if(Filter.Stat != null && filter.Stat.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "STAT" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.Stat;
		}
		
		if(Filter.At01 != null && filter.At01.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "AT01" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.At01;
		}
		
		if(Filter.Maxno != null && filter.Maxno.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "MAXNO" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.Maxno;
		}
		
		if(Filter.Allstat != null && filter.Allstat.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "ALLSTAT" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.Allstat;
		}
		
		if(Filter.__orderby != null && filter.__orderby.length()> 0)
		{
			if(filterString.length() > 0)
				filterString += ims.dto.NASMessageCodes.PAIRSEPARATOR;
			filterString += "__ORDERBY" + ims.dto.NASMessageCodes.ATTRIBUTEVALUESEPARATOR + filter.__orderby;
		}
		
		return filterString;	
	}
	
	private String encodeNASMessage()
	{
		String dataString = "";
		if(DataCollection.count() == 0)
			return dataString;
			


Please complete the code given below. 
# -*- coding: utf-8 -*-
##
## This file is part of Harvesting Kit.
## Copyright (C) 2013, 2014, 2015 CERN.
##
## Harvesting Kit is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## Harvesting Kit is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Harvesting Kit; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import re
import sys
import time
from os import pardir
from os.path import (join,
                     dirname,
                     basename)
try:
    from invenio.errorlib import register_exception
except ImportError:
    register_exception = lambda a=1, b=2: True
from harvestingkit.minidom_utils import (get_value_in_tag,
                                         xml_to_text)
from harvestingkit.utils import (format_arxiv_id,
                                 add_nations_field)
from harvestingkit.bibrecord import (
    record_add_field,
    create_record,
    record_xml_output,
)
from xml.dom.minidom import parse
class JATSParser(object):
    def __init__(self, tag_to_remove=None, extract_nations=False):
        self.references = None
        self.tag_to_remove = tag_to_remove
        self.extract_nations = extract_nations
    def get_article(self, path):
        return parse(open(path))
    def get_title(self, xml):
        try:
            return get_value_in_tag(xml, "article-title", tag_to_remove=self.tag_to_remove)
        except Exception:
            print >> sys.stderr, "Can't find title"
    def get_issn(self, xml):
        issns = xml.getElementsByTagName('issn')
        ret = None
        for issn in issns:
            if issn.getAttribute('date-type').encode('utf-8') == 'epub' or issn.getAttribute('pub-type').encode('utf-8') == 'epub':
                if issn.getAttribute("pub-type").encode('utf-8'):
                    ret = issn.getAttribute("pub-type").encode('utf-8')
                else:
                    ret = issn.getAttribute("date-type").encode('utf-8')
        if not ret and issns:
            ret = xml_to_text(issns[0])
        return ret
    def get_date(self, xml):
        dates = xml.getElementsByTagName('pub-date')
        ret = None
        for date in dates:
            if date.getAttribute('date-type').encode('utf-8') == 'epub' or date.getAttribute('pub-type').encode('utf-8') == 'epub':
                ret = get_value_in_tag(date, 'year')
        if not ret and dates:
            return dates[0]
        else:
            return ret
    def get_publication_information(self, xml):
        jid = get_value_in_tag(xml, "journal-title")
        journal = ""
        if "European Physical Journal" in jid:
            journal = "EPJC"
        try:
            art = xml.getElementsByTagName('article-meta')[0]
        except IndexError as err:
            register_exception()
            print >> sys.stderr, "ERROR: XML corrupted: %s" % err
            pass
        except Exception as err:
            register_exception()
            print >> sys.stderr, "ERROR: Exception captured: %s" % err
            pass
        issn = self.get_issn(art)
        volume = get_value_in_tag(art, "volume")
        issue = get_value_in_tag(art, "issue")
        year = self.get_date(art)
        first_page = get_value_in_tag(art, "fpage")
        last_page = get_value_in_tag(art, "lpage")
        doi = self.get_doi(art)
        return (journal, issn, volume, issue, first_page, last_page, year, doi)
    def get_doi(self, xml):
        ids = xml.getElementsByTagName('article-id')
        ret = ""
        for i in ids:
            if i.getAttribute('pub-id-type').encode('utf-8') == 'doi':
                ret = xml_to_text(i)
        if not ret:
            print >> sys.stdout, "Can't find DOI."
        return ret
    def _get_orcid(self, xml_author):
        try:
            contrib_id = xml_author.getElementsByTagName('contrib-id')[0]
            if contrib_id.getAttribute('contrib-id-type') == 'orcid':
                orcid_raw = xml_to_text(contrib_id)
                pattern = '\d\d\d\d-\d\d\d\d-\d\d\d\d-\d\d\d[\d|X]'
                return re.search(pattern, orcid_raw).group()
        except (IndexError, AttributeError):
            return None
    def get_authors(self, xml):
        authors = []
        for author in xml.getElementsByTagName("contrib"):
            # Springer puts colaborations in additional "contrib" tag so to
            # avoid having fake author with all affiliations we skip "contrib"
            # tag with "contrib" subtags.
            if author.getElementsByTagName("contrib"):
                continue
            tmp = {}
            surname = get_value_in_tag(author, "surname")
            if surname:
                tmp["surname"] = surname
            given_name = get_value_in_tag(author, "given-names")
            if given_name:
                tmp["given_name"] = given_name.replace('\n', ' ')
            if not surname and not given_name:
                tmp["name"] = get_value_in_tag(author, "string-name")
            # It's not there yet
            orcid = self._get_orcid(author)
            if orcid:
                tmp["orcid"] = 'ORCID:{0}'.format(orcid)
            # cross_refs = author.getElementsByTagName("ce:cross-ref")
            # if cross_refs:
            #     tmp["cross_ref"] = []
            #     for cross_ref in cross_refs:
            #         tmp["cross_ref"].append(cross_ref.getAttribute("refid").encode('utf-8'))
            tmp["affiliations_ids"] = []
            tmp["contact_ids"] = []
            xrefs = author.getElementsByTagName("xref")
            for x in xrefs:
                if x.getAttribute('ref-type').encode('utf-8') == 'aff':
                    tmp["affiliations_ids"].extend([a.encode('utf-8') for a in x.getAttribute('rid').split()])
                if x.getAttribute('ref-type').encode('utf-8') == 'corresp':
                    tmp["contact_ids"].extend([a.encode('utf-8') for a in x.getAttribute('rid').split()])
            authors.append(tmp)
        affiliations = {}
        for affiliation in xml.getElementsByTagName("aff"):
            aff_id = affiliation.getAttribute("id").encode('utf-8')
            # removes numbering in from affiliations
            text = re.sub(r'^(\d+,\ ?)', "", xml_to_text(affiliation, delimiter=", "))
            affiliations[aff_id] = text
        emails = {}
        for contact in xml.getElementsByTagName("corresp"):
            contact_id = contact.getAttribute("id").encode('utf-8')
            if contact.getElementsByTagName('email'):
                text = xml_to_text(contact.getElementsByTagName('email')[0])
                emails[contact_id] = text
        implicit_affilations = True
        for author in authors:
            matching_ref = [ref for ref in author.get("affiliations_ids") if ref in affiliations]
            if matching_ref:
                implicit_affilations = False
                author["affiliation"] = []
                for i in xrange(0, len(matching_ref)):
                    author["affiliation"].append(affiliations[matching_ref[i]])
            matching_contact = [cont for cont in author.get('contact_ids') if cont in emails]
            if matching_contact:
                author["email"] = emails[matching_contact[0]]
        if implicit_affilations and len(affiliations) > 1:
            print >> sys.stderr, "Implicit affiliations are used, but there are more than one affiliation: %s" % affiliations
        if implicit_affilations and len(affiliations) >= 1:
            for author in authors:
                author["affiliation"] = []
                for aff in affiliations.values():
                    author["affiliation"].append(aff)
        return authors
    def get_abstract(self, xml):
        try:
            return get_value_in_tag(xml, "abstract", tag_to_remove=self.tag_to_remove).replace("Abstract", "", 1)
        except Exception:
            print >> sys.stderr, "Can't find abstract"
    def get_copyright(self, xml, logger=None):
        tags = ["copyright-holder", "copyright-statement"]
        for tag in tags:
            if tag is "copyright-holder":
                ret = get_value_in_tag(xml, tag)
                if not ret:
                    if logger:
                        logger.info("Can't find copyright, trying different tag.")
                    print >> sys.stderr, "Can't find copyright, trying different tag."
                else:
                    return ret
            else:
                ret = get_value_in_tag(xml, tag)
                if not ret:
                    if logger:
                        logger.info("Can't find copyright")
                    print >> sys.stderr, "Can't find copyright"
                else:
                    ret = ret.split('.')
                    return ret[0]
    def get_keywords(self, xml):
        try:
            kwd_groups = xml.getElementsByTagName('kwd-group')
            pacs = []
            other = []
            for kwd_group in kwd_groups:
                if kwd_group.getAttribute('kwd-group-type').encode('utf-8') == "pacs":
                    pacs = [xml_to_text(keyword, tag_to_remove=self.tag_to_remove) for keyword in kwd_group.getElementsByTagName("kwd")]
                else:
                    other = [xml_to_text(keyword, tag_to_remove=self.tag_to_remove) for keyword in kwd_group.getElementsByTagName("kwd")]
            return {"pacs": pacs, "other": other}
        except Exception:
            print >> sys.stderr, "Can't find keywords"
    def get_ref_link(self, xml, name):
        links = xml.getElementsByTagName('ext-link')
        ret = None
        for link in links:
            if name in link.getAttribute("xlink:href").encode('utf-8'):
                ret = xml_to_text(link).strip()
        if not ret:
            links = xml.getElementsByTagName('elocation-id')
            for link in links:
                if name in link.getAttribute("content-type").encode('utf-8'):
                    ret = xml_to_text(link).strip()
        return ret
    def get_page_count(self, xml):
        counts = xml.getElementsByTagName("counts")
        if counts:
            page_count = counts[0].getElementsByTagName("page-count")
            if page_count:
                return page_count[0].getAttribute("count").encode('utf-8')
            else:
                return None
        else:
            return None
    def get_publication_date(self, xml, logger=None):
        date_xmls = xml.getElementsByTagName('pub-date')
        day = None
        month = None
        year = None
        if date_xmls:
            for date_xml in date_xmls:
                if date_xml.hasAttribute('pub-type'):
                    if date_xml.getAttribute('pub-type') == "epub":
                        day = get_value_in_tag(date_xml, "day")
                        month = get_value_in_tag(date_xml, "month")
                        year = get_value_in_tag(date_xml, "year")
                if not year:
                    day = get_value_in_tag(date_xml, "day")
                    month = get_value_in_tag(date_xml, "month")
                    year = get_value_in_tag(date_xml, "year")
            if logger:
                logger.info('%s-%s-%s' % (year, month, day))
            return '%s-%s-%s' % (year, month, day)
        else:
            print >> sys.stderr, "Can't find publication date. Using 'today'."
            if logger:
                logger.info("Can't find publication date. Using 'today'.")
            return time.strftime('%Y-%m-%d')
    def get_references(self, xml):
        references = []
        for reference in xml.getElementsByTagName("ref"):
            plain_text = None
            try:
                ref_type = reference.getElementsByTagName('mixed-citation')[0]
                ref_type = ref_type.getAttribute('publication-type').encode('utf-8')
            except:
                ref_type = reference.getElementsByTagName('citation')[0]
                ref_type = ref_type.getAttribute('publication-type').encode('utf-8')
            label = get_value_in_tag(reference, "label").strip('.')
            authors = []
            for author in reference.getElementsByTagName("name"):
                given_name = get_value_in_tag(author, "given-names")
                surname = get_value_in_tag(author, "surname")
                if given_name:
                    name = "%s, %s" % (surname, given_name)
                else:
                    name = surname
                if name.strip().split() == []:
                    name = get_value_in_tag(author, "string-name")
                authors.append(name)
            doi_tag = reference.getElementsByTagName("pub-id")
            doi = ""
            for tag in doi_tag:
                if tag.getAttribute("pub-id-type") == "doi":
                    doi = xml_to_text(tag)
            issue = get_value_in_tag(reference, "issue")
            page = get_value_in_tag(reference, "fpage")
            page_last = get_value_in_tag(reference, "lpage")
            title = get_value_in_tag(reference, "source")
            volume = get_value_in_tag(reference, "volume")
            year = get_value_in_tag(reference, "year")
            ext_link = format_arxiv_id(self.get_ref_link(reference, "arxiv"))
            if ref_type != 'journal':
                try:
                    plain_text = get_value_in_tag(reference,
                                                  "mixed-citation",
                                                  tag_to_remove=self.tag_to_remove)
                except:
                    plain_text = get_value_in_tag(reference,
                                                  "citation",
                                                  tag_to_remove=self.tag_to_remove)
            references.append((label, authors, doi,
                               issue, page, page_last,
                               title, volume, year,
                               ext_link, plain_text))
        self.references = references
    def get_record(self, f_path, publisher=None, collection=None, logger=None):
        xml = self.get_article(f_path)
        rec = create_record()
        title = self.get_title(xml)
        if title:
            record_add_field(rec, '245', subfields=[('a', title)])
        record_add_field(rec, '260', subfields=[('c', self.get_publication_date(xml, logger))])
        journal, issn, volume, issue, first_page, last_page, year, doi = self.get_publication_information(xml)
        if logger:
            logger.info("Creating record: %s %s" % (join(f_path, pardir), doi))
        if doi:
            record_add_field(rec, '024', ind1='7', subfields=[('a', doi), ('2', 'DOI')])
        authors = self.get_authors(xml)
        first_author = True
        for author in authors:
            if author.get('surname'):
                subfields = [('a', '%s, %s' % (author.get('surname'), author.get('given_name') or author.get('initials', '')))]
            else:
                subfields = [('a', '%s' % (author.get('name', '')))]
            if 'orcid' in author:
                subfields.append(('j', author['orcid']))
            if 'affiliation' in author:
                for aff in author["affiliation"]:
                    subfields.append(('v', aff))
                if self.extract_nations:
                    add_nations_field(subfields)
            if author.get('email'):
                    subfields.append(('m', author['email']))
            if first_author:
                record_add_field(rec, '100', subfields=subfields)
                first_author = False
            else:
                record_add_field(rec, '700', subfields=subfields)
        page_count = self.get_page_count(xml)
        if page_count:


Please complete the code given below. 
package cern.colt.matrix.tint.impl;
import cern.colt.list.tint.IntArrayList;
import cern.colt.matrix.tint.IntMatrix1D;
import cern.colt.matrix.tint.IntMatrix1DProcedure;
import cern.colt.matrix.tint.IntMatrix2D;
import cern.colt.matrix.tint.IntMatrix2DTest;
import cern.jet.math.tint.IntFunctions;
import edu.emory.mathcs.utils.ConcurrencyUtils;
public class DiagonalIntMatrix2DTest extends IntMatrix2DTest {
    protected int DLENGTH;
    protected int DINDEX;
    public DiagonalIntMatrix2DTest(String arg0) {
        super(arg0);
    }
    protected void createMatrices() throws Exception {
        DINDEX = 3;
        A = new DiagonalIntMatrix2D(NROWS, NCOLUMNS, DINDEX);
        B = new DiagonalIntMatrix2D(NROWS, NCOLUMNS, DINDEX);
        Bt = new DiagonalIntMatrix2D(NCOLUMNS, NROWS, -DINDEX);
        DLENGTH = ((DiagonalIntMatrix2D) A).diagonalLength();
    }
    protected void populateMatrices() {
        ConcurrencyUtils.setThreadsBeginN_2D(1);
        if (DINDEX >= 0) {
            for (int r = 0; r < DLENGTH; r++) {
                A.setQuick(r, r + DINDEX, Math.max(1, rand.nextInt() % A.rows()));
            }
            for (int r = 0; r < DLENGTH; r++) {
                B.setQuick(r, r + DINDEX, Math.max(1, rand.nextInt() % A.rows()));
            }
            for (int r = 0; r < DLENGTH; r++) {
                Bt.setQuick(r - DINDEX, r, Math.max(1, rand.nextInt() % A.rows()));
            }
        } else {
            for (int r = 0; r < DLENGTH; r++) {
                A.setQuick(r - DINDEX, r, Math.max(1, rand.nextInt() % A.rows()));
            }
            for (int r = 0; r < DLENGTH; r++) {
                B.setQuick(r - DINDEX, r, Math.max(1, rand.nextInt() % A.rows()));
            }
            for (int r = 0; r < DLENGTH; r++) {
                Bt.setQuick(r, r + DINDEX, Math.max(1, rand.nextInt() % A.rows()));
            }
        }
    }
    public void testAssignInt() {
        int value = Math.max(1, rand.nextInt() % A.rows());
        A.assign(value);
        if (DINDEX >= 0) {
            for (int r = 0; r < DLENGTH; r++) {
                assertEquals(value, A.getQuick(r, r + DINDEX));
            }
        } else {
            for (int r = 0; r < DLENGTH; r++) {
                assertEquals(value, A.getQuick(r - DINDEX, r));
            }
        }
    }
    public void testAssignIntArrayArray() {
        int[][] expected = new int[NROWS][NCOLUMNS];
        for (int r = 0; r < NROWS; r++) {
            for (int c = 0; c < NCOLUMNS; c++) {
                expected[r][c] = Math.max(1, rand.nextInt() % A.rows());
            }
        }
        A.assign(expected);
        if (DINDEX >= 0) {
            for (int r = 0; r < DLENGTH; r++) {
                assertEquals(expected[r][r + DINDEX], A.getQuick(r, r + DINDEX));
            }
        } else {
            for (int r = 0; r < DLENGTH; r++) {
                assertEquals(expected[r - DINDEX][r], A.getQuick(r - DINDEX, r));
            }
        }
    }
    public void testAssignIntFunction() {
        IntMatrix2D Acopy = A.copy();
        A.assign(IntFunctions.neg);
        if (DINDEX >= 0) {
            for (int r = 0; r < DLENGTH; r++) {
                int expected = -Acopy.getQuick(r, r + DINDEX);
                assertEquals(expected, A.getQuick(r, r + DINDEX));
            }
        } else {
            for (int r = 0; r < DLENGTH; r++) {
                int expected = -Acopy.getQuick(r - DINDEX, r);
                assertEquals(expected, A.getQuick(r - DINDEX, r));
            }
        }
    }
    public void testAssignIntMatrix2DIntIntFunction() {
        IntMatrix2D Acopy = A.copy();
        A.assign(B, IntFunctions.div);
        if (DINDEX >= 0) {
            for (int r = 0; r < DLENGTH; r++) {
                assertEquals(Acopy.getQuick(r, r + DINDEX) / B.getQuick(r, r + DINDEX), A.getQuick(r, r + DINDEX));
            }
        } else {
            for (int r = 0; r < DLENGTH; r++) {
                assertEquals(Acopy.getQuick(r - DINDEX, r) / B.getQuick(r - DINDEX, r), A.getQuick(r - DINDEX, r));
            }
        }
    }
    public void testAssignIntMatrix2DIntIntFunctionIntArrayListIntArrayList() {
        IntArrayList rowList = new IntArrayList();
        IntArrayList columnList = new IntArrayList();
        if (DINDEX >= 0) {
            for (int r = 0; r < DLENGTH; r++) {
                rowList.add(r);
                columnList.add(r + DINDEX);
            }
            IntMatrix2D Acopy = A.copy();
            A.assign(B, IntFunctions.div, rowList, columnList);
            for (int r = 0; r < DLENGTH; r++) {
                assertEquals(Acopy.getQuick(r, r + DINDEX) / B.getQuick(r, r + DINDEX), A.getQuick(r, r + DINDEX));
            }
        } else {
            for (int r = 0; r < DLENGTH; r++) {
                rowList.add(r - DINDEX);
                columnList.add(r);
            }
            IntMatrix2D Acopy = A.copy();
            A.assign(B, IntFunctions.div, rowList, columnList);
            for (int r = 0; r < DLENGTH; r++) {
                assertEquals(Acopy.getQuick(r - DINDEX, r) / B.getQuick(r - DINDEX, r), A.getQuick(r - DINDEX, r));
            }
        }
    }
    public void testCardinality() {
        int card = A.cardinality();
        assertEquals(DLENGTH, card);
    }
    public void testMaxLocation() {
        A.assign(0);
        if (DINDEX >= 0) {
            A.setQuick(NROWS / 3, NROWS / 3 + DINDEX, 7);
            A.setQuick(NROWS / 2, NROWS / 2 + DINDEX, 1);
            int[] maxAndLoc = A.getMaxLocation();
            assertEquals(7, maxAndLoc[0]);
            assertEquals(NROWS / 3, (int) maxAndLoc[1]);
            assertEquals(NROWS / 3 + DINDEX, (int) maxAndLoc[2]);
        } else {
            A.setQuick(NROWS / 3 - DINDEX, NROWS / 3, 7);
            A.setQuick(NROWS / 2 - DINDEX, NROWS / 2, 1);
            int[] maxAndLoc = A.getMaxLocation();
            assertEquals(7, maxAndLoc[0]);
            assertEquals(NROWS / 3 - DINDEX, (int) maxAndLoc[1]);
            assertEquals(NROWS / 3, (int) maxAndLoc[2]);
        }
    }
    public void testMinLocation() {
        A.assign(0);
        if (DINDEX >= 0) {
            A.setQuick(NROWS / 3, NROWS / 3 + DINDEX, -7);
            A.setQuick(NROWS / 2, NROWS / 2 + DINDEX, -1);
            int[] minAndLoc = A.getMinLocation();
            assertEquals(-7, minAndLoc[0]);
            assertEquals(NROWS / 3, (int) minAndLoc[1]);
            assertEquals(NROWS / 3 + DINDEX, (int) minAndLoc[2]);
        } else {
            A.setQuick(NROWS / 3 - DINDEX, NROWS / 3, -7);
            A.setQuick(NROWS / 2 - DINDEX, NROWS / 2, -1);
            int[] minAndLoc = A.getMinLocation();
            assertEquals(-7, minAndLoc[0]);
            assertEquals(NROWS / 3 - DINDEX, (int) minAndLoc[1]);
            assertEquals(NROWS / 3, (int) minAndLoc[2]);
        }
    }
    public void testGetNegativeValues() {
        A.assign(0);
        if (DINDEX >= 0) {
            A.setQuick(NROWS / 3, NROWS / 3 + DINDEX, -7);
            A.setQuick(NROWS / 2, NROWS / 2 + DINDEX, -1);
            IntArrayList rowList = new IntArrayList();
            IntArrayList columnList = new IntArrayList();
            IntArrayList valueList = new IntArrayList();
            A.getNegativeValues(rowList, columnList, valueList);
            assertEquals(2, rowList.size());
            assertEquals(2, columnList.size());
            assertEquals(2, valueList.size());
            assertTrue(rowList.contains(NROWS / 3));
            assertTrue(rowList.contains(NROWS / 2));
            assertTrue(columnList.contains(NROWS / 3 + DINDEX));
            assertTrue(columnList.contains(NROWS / 2 + DINDEX));
            assertTrue(valueList.contains(-7));
            assertTrue(valueList.contains(-1));
        } else {
            A.setQuick(NROWS / 3 - DINDEX, NROWS / 3, -7);
            A.setQuick(NROWS / 2 - DINDEX, NROWS / 2, -1);
            IntArrayList rowList = new IntArrayList();
            IntArrayList columnList = new IntArrayList();
            IntArrayList valueList = new IntArrayList();
            A.getNegativeValues(rowList, columnList, valueList);
            assertEquals(2, rowList.size());
            assertEquals(2, columnList.size());
            assertEquals(2, valueList.size());
            assertTrue(rowList.contains(NROWS / 3 - DINDEX));
            assertTrue(rowList.contains(NROWS / 2 - DINDEX));
            assertTrue(columnList.contains(NROWS / 3));
            assertTrue(columnList.contains(NROWS / 2));
            assertTrue(valueList.contains(-7));
            assertTrue(valueList.contains(-1));
        }
    }
    public void testGetNonZeros() {
        A.assign(0);
        if (DINDEX >= 0) {
            A.setQuick(NROWS / 3, NROWS / 3 + DINDEX, 7);
            A.setQuick(NROWS / 2, NROWS / 2 + DINDEX, 1);
            IntArrayList rowList = new IntArrayList();
            IntArrayList columnList = new IntArrayList();
            IntArrayList valueList = new IntArrayList();
            A.getNonZeros(rowList, columnList, valueList);
            assertEquals(2, rowList.size());
            assertEquals(2, columnList.size());
            assertEquals(2, valueList.size());
            assertTrue(rowList.contains(NROWS / 3));
            assertTrue(rowList.contains(NROWS / 2));
            assertTrue(columnList.contains(NROWS / 3 + DINDEX));
            assertTrue(columnList.contains(NROWS / 2 + DINDEX));
            assertTrue(valueList.contains(7));
            assertTrue(valueList.contains(1));
        } else {
            A.setQuick(NROWS / 3 - DINDEX, NROWS / 3, 7);
            A.setQuick(NROWS / 2 - DINDEX, NROWS / 2, 1);
            IntArrayList rowList = new IntArrayList();
            IntArrayList columnList = new IntArrayList();
            IntArrayList valueList = new IntArrayList();
            A.getNonZeros(rowList, columnList, valueList);
            assertEquals(2, rowList.size());
            assertEquals(2, columnList.size());
            assertEquals(2, valueList.size());
            assertTrue(rowList.contains(NROWS / 3 - DINDEX));
            assertTrue(rowList.contains(NROWS / 2 - DINDEX));
            assertTrue(columnList.contains(NROWS / 3));
            assertTrue(columnList.contains(NROWS / 2));
            assertTrue(valueList.contains(7));
            assertTrue(valueList.contains(1));
        }
    }
    public void testGetPositiveValues() {
        A.assign(0);
        if (DINDEX >= 0) {
            A.setQuick(NROWS / 3, NROWS / 3 + DINDEX, 7);
            A.setQuick(NROWS / 2, NROWS / 2 + DINDEX, 1);
            IntArrayList rowList = new IntArrayList();
            IntArrayList columnList = new IntArrayList();
            IntArrayList valueList = new IntArrayList();
            A.getPositiveValues(rowList, columnList, valueList);
            assertEquals(2, rowList.size());
            assertEquals(2, columnList.size());
            assertEquals(2, valueList.size());
            assertTrue(rowList.contains(NROWS / 3));
            assertTrue(rowList.contains(NROWS / 2));
            assertTrue(columnList.contains(NROWS / 3 + DINDEX));
            assertTrue(columnList.contains(NROWS / 2 + DINDEX));
            assertTrue(valueList.contains(7));
            assertTrue(valueList.contains(1));
        } else {
            A.setQuick(NROWS / 3 - DINDEX, NROWS / 3, 7);
            A.setQuick(NROWS / 2 - DINDEX, NROWS / 2, 1);
            IntArrayList rowList = new IntArrayList();
            IntArrayList columnList = new IntArrayList();
            IntArrayList valueList = new IntArrayList();
            A.getPositiveValues(rowList, columnList, valueList);
            assertEquals(2, rowList.size());
            assertEquals(2, columnList.size());
            assertEquals(2, valueList.size());
            assertTrue(rowList.contains(NROWS / 3 - DINDEX));
            assertTrue(rowList.contains(NROWS / 2 - DINDEX));
            assertTrue(columnList.contains(NROWS / 3));
            assertTrue(columnList.contains(NROWS / 2));
            assertTrue(valueList.contains(7));
            assertTrue(valueList.contains(1));
        }
    }
    public void testToArray() {
        int[][] array = A.toArray();
        assertTrue(NROWS == array.length);
        for (int r = 0; r < NROWS; r++) {
            assertTrue(NCOLUMNS == array[r].length);
            for (int c = 0; c < NCOLUMNS; c++) {
                assertEquals(array[r][c], A.getQuick(r, c));
            }
        }
    }
    public void testVectorize() {
        IntMatrix1D Avec = A.vectorize();
        int idx = 0;
        for (int c = 0; c < NCOLUMNS; c++) {
            for (int r = 0; r < NROWS; r++) {
                assertEquals(A.getQuick(r, c), Avec.getQuick(idx++));
            }
        }
    }
    public void testViewColumn() {
        IntMatrix1D col = A.viewColumn(NCOLUMNS / 2);
        assertEquals(NROWS, col.size());
        for (int r = 0; r < NROWS; r++) {
            assertEquals(A.getQuick(r, NCOLUMNS / 2), col.getQuick(r));
        }
    }
    public void testViewColumnFlip() {
        IntMatrix2D B = A.viewColumnFlip();
        assertEquals(A.size(), B.size());
        for (int r = 0; r < NROWS; r++) {
            for (int c = 0; c < NCOLUMNS; c++) {


Please complete the code given below. 
# coding: utf8
# This file is part of Scapy
# Scapy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# any later version.
#
# Scapy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Scapy. If not, see <http://www.gnu.org/licenses/>.
# scapy.contrib.description = EtherNet/IP
# scapy.contrib.status = loads
# Copyright (C) 2019 Jose Diogo Monteiro <jdlopes@student.dei.uc.pt>
# Based on https://github.com/scy-phy/scapy-cip-enip
# Routines for EtherNet/IP (Industrial Protocol) dissection
# EtherNet/IP Home: www.odva.org
import struct
from scapy.packet import Packet, bind_layers
from scapy.layers.inet import TCP
from scapy.fields import LEShortField, LEShortEnumField, LEIntEnumField, \
    LEIntField, LELongField, FieldLenField, PacketListField, ByteField, \
    PacketField, MultipleTypeField, StrLenField, StrFixedLenField, \
    XLEIntField, XLEStrLenField
_commandIdList = {
    0x0004: "ListServices",  # Request Struct Don't Have Command Spec Data
    0x0063: "ListIdentity",  # Request Struct Don't Have Command Spec Data
    0x0064: "ListInterfaces",  # Request Struct Don't Have Command Spec Data
    0x0065: "RegisterSession",  # Request Structure = Reply Structure
    0x0066: "UnregisterSession",  # Don't Have Command Specific Data
    0x006f: "SendRRData",  # Request Structure = Reply Structure
    0x0070: "SendUnitData",  # There is no reply
    0x0072: "IndicateStatus",
    0x0073: "Cancel"
}
_statusList = {
    0: "success",
    1: "invalid_cmd",
    2: "no_resources",
    3: "incorrect_data",
    100: "invalid_session",
    101: "invalid_length",
    105: "unsupported_prot_rev"
}
_itemID = {
    0x0000: "Null Address Item",
    0x00a1: "Connection-based Address Item",
    0x00b1: "Connected Transport packet Data Item",
    0x00b2: "Unconnected message Data Item",
    0x8000: "Sockaddr Info, originator-to-target Data Item",
    0x8001: "Sockaddr Info, target-to-originator Data Item"
}
class ItemData(Packet):
    """Common Packet Format"""
    name = "Item Data"
    fields_desc = [
        LEShortEnumField("typeId", 0, _itemID),
        LEShortField("length", 0),
        XLEStrLenField("data", "", length_from=lambda pkt: pkt.length),
    ]
    def extract_padding(self, s):
        return '', s
class EncapsulatedPacket(Packet):
    """Encapsulated Packet"""
    name = "Encapsulated Packet"
    fields_desc = [LEShortField("itemCount", 2), PacketListField(
        "item", None, ItemData, count_from=lambda pkt: pkt.itemCount), ]
class BaseSendPacket(Packet):
    """ Abstract Class"""
    fields_desc = [
        LEIntField("interfaceHandle", 0),
        LEShortField("timeout", 0),
        PacketField("encapsulatedPacket", None, EncapsulatedPacket),
    ]
class CommandSpecificData(Packet):
    """Command Specific Data Field Default"""
    pass
class ENIPSendUnitData(BaseSendPacket):
    """Send Unit Data Command Field"""
    name = "ENIPSendUnitData"
class ENIPSendRRData(BaseSendPacket):
    """Send RR Data Command Field"""
    name = "ENIPSendRRData"
class ENIPListInterfacesReplyItems(Packet):
    """List Interfaces Items Field"""
    name = "ENIPListInterfacesReplyItems"
    fields_desc = [
        LEIntField("itemTypeCode", 0),
        FieldLenField("itemLength", 0, length_of="itemData"),
        StrLenField("itemData", "", length_from=lambda pkt: pkt.itemLength),
    ]
class ENIPListInterfacesReply(Packet):
    """List Interfaces Command Field"""
    name = "ENIPListInterfacesReply"
    fields_desc = [
        FieldLenField("itemCount", 0, count_of="identityItems"),
        PacketField("identityItems", 0, ENIPListInterfacesReplyItems),
    ]
class ENIPListIdentityReplyItems(Packet):
    """List Identity Items Field"""
    name = "ENIPListIdentityReplyItems"
    fields_desc = [
        LEIntField("itemTypeCode", 0),
        FieldLenField("itemLength", 0, length_of="itemData"),
        StrLenField("itemData", "", length_from=lambda pkt: pkt.item_length),
    ]
class ENIPListIdentityReply(Packet):
    """List Identity Command Field"""
    name = "ENIPListIdentityReply"
    fields_desc = [
        FieldLenField("itemCount", 0, count_of="identityItems"),
        PacketField("identityItems", None, ENIPListIdentityReplyItems),
    ]
class ENIPListServicesReplyItems(Packet):
    """List Services Items Field"""
    name = "ENIPListServicesReplyItems"
    fields_desc = [
        LEIntField("itemTypeCode", 0),
        LEIntField("itemLength", 0),
        ByteField("version", 1),
        ByteField("flag", 0),
        StrFixedLenField("serviceName", None, 16 * 4),
    ]
class ENIPListServicesReply(Packet):
    """List Services Command Field"""
    name = "ENIPListServicesReply"
    fields_desc = [
        FieldLenField("itemCount", 0, count_of="identityItems"),
        PacketField("targetItems", None, ENIPListServicesReplyItems),
    ]
class ENIPRegisterSession(CommandSpecificData):
    """Register Session Command Field"""
    name = "ENIPRegisterSession"
    fields_desc = [
        LEShortField("protocolVersion", 1),
        LEShortField("options", 0)
    ]
class ENIPTCP(Packet):
    """Ethernet/IP packet over TCP"""
    name = "ENIPTCP"
    fields_desc = [
        LEShortEnumField("commandId", None, _commandIdList),
        LEShortField("length", 0),
        XLEIntField("session", 0),
        LEIntEnumField("status", None, _statusList),
        LELongField("senderContext", 0),
        LEIntField("options", 0),
        MultipleTypeField(
            [
                # List Services Reply
                (PacketField("commandSpecificData", ENIPListServicesReply,
                             ENIPListServicesReply),
                 lambda pkt: pkt.commandId == 0x4),
                # List Identity Reply
                (PacketField("commandSpecificData", ENIPListIdentityReply,
                             ENIPListIdentityReply),
                 lambda pkt: pkt.commandId == 0x63),
                # List Interfaces Reply
                (PacketField("commandSpecificData", ENIPListInterfacesReply,
                             ENIPListInterfacesReply),
                 lambda pkt: pkt.commandId == 0x64),
                # Register Session
                (PacketField("commandSpecificData", ENIPRegisterSession,
                             ENIPRegisterSession),
                 lambda pkt: pkt.commandId == 0x65),
                # Send RR Data
                (PacketField("commandSpecificData", ENIPSendRRData,
                             ENIPSendRRData),


Please complete the code given below. 
/*
 *  GeoBatch - Open Source geospatial batch processing system
 *  http://code.google.com/p/geobatch/
 *  Copyright (C) 2007-2008-2009 GeoSolutions S.A.S.
 *  http://www.geo-solutions.it
 *
 *  GPLv3 + Classpath exception
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package it.geosolutions.geobatch.registry.harvest;
import it.geosolutions.filesystemmonitor.monitor.FileSystemMonitorEvent;
import it.geosolutions.filesystemmonitor.monitor.FileSystemMonitorNotifications;
import it.geosolutions.geobatch.catalog.file.FileBaseCatalog;
import it.geosolutions.geobatch.global.CatalogHolder;
import it.geosolutions.geobatch.jgsflodess.utils.io.JGSFLoDeSSIOUtils;
import it.geosolutions.geobatch.jgsflodess.utils.io.rest.PublishingRestletGlobalConfig;
import it.geosolutions.geobatch.metocs.jaxb.model.MetocElementType;
import it.geosolutions.geobatch.metocs.jaxb.model.Metocs;
import it.geosolutions.geobatch.registry.RegistryActionConfiguration;
import it.geosolutions.geobatch.registry.RegistryConfiguratorAction;
import it.geosolutions.geobatch.utils.IOUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Queue;
import java.util.UUID;
import java.util.logging.Level;
import javax.media.jai.JAI;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.apache.commons.io.FilenameUtils;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridFormatFinder;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.LinearTransform;
import org.opengis.coverage.grid.Format;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.coverage.grid.GridGeometry;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.Matrix;
/**
 * 
 * TODO: DOCUMENT ME !!
 * 
 */
public class RegistryHarvestingConfigurator extends RegistryConfiguratorAction<FileSystemMonitorEvent> {
	/**
	 * GeoTIFF Writer Default Params
	 */
	public final static String GEOSERVER_VERSION = "2.x";
	protected RegistryHarvestingConfigurator(
			RegistryActionConfiguration configuration) throws IOException {
		super(configuration);
	}
	/**
	 * EXECUTE METHOD 
	 */
	public Queue<FileSystemMonitorEvent> execute(
			Queue<FileSystemMonitorEvent> events) throws Exception {
		if (LOGGER.isLoggable(Level.INFO))
			LOGGER.info("Starting with processing...");
		try {
			// looking for file
			if (events.size() == 0)
				throw new IllegalArgumentException("Wrong number of elements for this action: " + events.size());
			
			List<FileSystemMonitorEvent> generatedEvents = new ArrayList<FileSystemMonitorEvent>();
			
			while (events.size() > 0) {
				FileSystemMonitorEvent event = events.remove();
				// //
				// data flow configuration and dataStore name must not be null.
				// //
				if (configuration == null) {
					LOGGER.log(Level.SEVERE, "DataFlowConfig is null.");
					throw new IllegalStateException("DataFlowConfig is null.");
				}
				// ////////////////////////////////////////////////////////////////////
				//
				// Initializing input variables
				//
				// ////////////////////////////////////////////////////////////////////
				final File workingDir = IOUtils.findLocation(configuration.getWorkingDirectory(), new File(
						((FileBaseCatalog) CatalogHolder.getCatalog()).getBaseDirectory()));
				// ////////////////////////////////////////////////////////////////////
				//
				// Checking input files.
				//
				// ////////////////////////////////////////////////////////////////////
				if ((workingDir == null) || !workingDir.exists()
						|| !workingDir.isDirectory()) {
					LOGGER.log(Level.SEVERE, "WorkingDirectory is null or does not exist.");
					throw new IllegalStateException("WorkingDirectory is null or does not exist.");
				}
				// ... BUSINESS LOGIC ... //
				final File inputFile = event.getSource();
				String inputFileName = inputFile.getAbsolutePath();
				final String filePrefix = FilenameUtils.getBaseName(inputFileName);
				final String fileSuffix = FilenameUtils.getExtension(inputFileName);
				final String fileNameFilter = getConfiguration().getStoreFilePrefix();
				String baseFileName = null;
				if (fileNameFilter != null) {
					if ((filePrefix.equals(fileNameFilter) || filePrefix.matches(fileNameFilter))
							&& "layer".equalsIgnoreCase(fileSuffix)) {
						// etj: are we missing something here?
						baseFileName = filePrefix;
					}
				} else if ("layer".equalsIgnoreCase(fileSuffix)) {
					baseFileName = filePrefix;
				}
				if (baseFileName == null) {
					LOGGER.log(Level.SEVERE, "Unexpected file '" + inputFileName + "'");
					throw new IllegalStateException("Unexpected file '" + inputFileName + "'");
				}
				Properties props = new Properties();
				//try retrieve data from file
				try {
					props.load(new FileInputStream(inputFile));
				}
				//catch exception in case properties file does not exist
				catch(IOException e) {
					LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
				}
				final String namespace = props.getProperty("namespace");
				final String metocFields = props.getProperty("metocFields");
				final String storeid = props.getProperty("storeid");
				final String layerid = props.getProperty("layerid");
				final String driver = props.getProperty("driver");
				final String path = new File(inputFile.getParentFile(), props.getProperty("path")).getAbsolutePath();
				
				final File metadataTemplate = IOUtils.findLocation(configuration.getMetocHarvesterXMLTemplatePath(), new File(((FileBaseCatalog) CatalogHolder.getCatalog()).getBaseDirectory()));
				
				boolean res = harvest(
						new File(PublishingRestletGlobalConfig.getRootDirectory()), 
						new File(path), 
						metadataTemplate, 
						driver, 
						configuration.getGeoserverURL(), 
						configuration.getRegistryURL(), 
						configuration.getProviderURL(), 
						new Date().getTime(), 
						namespace, 
						metocFields, 
						layerid, 
						"DOWN"
				);
				
				if (res) {
					// forwarding to the next Action
					if (LOGGER.isLoggable(Level.FINE))
						LOGGER.fine("RegistryHarvestingAction ... forwarding to the next Action: " + inputFile.getAbsolutePath());
					/** TODO: remove this --- generatedEvents.add(new FileSystemMonitorEvent(inputFile, FileSystemMonitorNotifications.FILE_ADDED)); **/
				}
			}
			
			/** TODO: remove this --- if (generatedEvents != null)
				events.addAll(generatedEvents); **/
			return events;
		} catch (Throwable t) {
			LOGGER.log(Level.SEVERE, t.getLocalizedMessage(), t);
			JAI.getDefaultInstance().getTileCache().flush();
			return null;
		} finally {
			JAI.getDefaultInstance().getTileCache().flush();
		}
	}
	/**
	 * 
	 * @param outDir
	 * @param sourceFile
	 * @param metadataTemplate
	 * @param sourceFileType
	 * @param geoserverURL
	 * @param registryURL
	 * @param providerURL
	 * @param timestamp
	 * @param namespace
	 * @param metocFields
	 * @param coverageName
	 * @param zOrder
	 * @return
	 * @throws JAXBException
	 * @throws IOException
	 * @throws FactoryException
	 * @throws ParseException
	 */
	public boolean harvest(
			final File outDir, 
			final File sourceFile,
			final File metadataTemplate,
			final String sourceFileType,
			final String geoserverURL,
			final String registryURL,
			final String providerURL,
			final long timestamp, 
			final String namespace, 
			final String metocFields,
			final String coverageName, 
			final String zOrder
	) throws JAXBException, IOException, FactoryException, ParseException {
		// CoverageName Format:
		//  CRUISEEXP_MODELNAME-MODELTYPE_VARNAME(-u/v/mag/dir)_ZLEV_BASETIMEYYYYMMDD_BASETIMEHHHMMSS_FCSTTIMEYYYYMMDD_FCSTTIMEHHHMMSS_TAU
		
		//Grabbing the Variables Dictionary
		JAXBContext context = JAXBContext.newInstance(Metocs.class);
		Unmarshaller um = context.createUnmarshaller();
		
		File metocDictionaryFile = IOUtils.findLocation(configuration.getMetocDictionaryPath(), new File(((FileBaseCatalog) CatalogHolder.getCatalog()).getBaseDirectory())); 
		Metocs metocDictionary = (Metocs) um.unmarshal(new FileReader(metocDictionaryFile));
		
		// reading GeoTIFF file
		final AbstractGridCoverage2DReader reader = ((AbstractGridFormat) acquireFormat(sourceFileType)).getReader(sourceFile.toURI().toURL());


Please complete the code given below. 
package com.garbagemule.MobArena.waves;
import java.util.Arrays;
import java.util.List;
import org.bukkit.DyeColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.*;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.inventory.ItemStack;
import com.garbagemule.MobArena.MobArena;
import com.garbagemule.MobArena.framework.Arena;
public enum MACreature
{
    // Default creatures
    ZOMBIE(EntityType.ZOMBIE),            ZOMBIES(EntityType.ZOMBIE), 
    SKELETON(EntityType.SKELETON),        SKELETONS(EntityType.SKELETON),
    SPIDER(EntityType.SPIDER),            SPIDERS(EntityType.SPIDER),
    CREEPER(EntityType.CREEPER),          CREEPERS(EntityType.CREEPER),
    WOLF(EntityType.WOLF),                WOLVES(EntityType.WOLF),
    
    // Special creatures
    ZOMBIEPIGMAN(EntityType.PIG_ZOMBIE),  ZOMBIEPIGMEN(EntityType.PIG_ZOMBIE),
    POWEREDCREEPER(EntityType.CREEPER),   POWEREDCREEPERS(EntityType.CREEPER),
    ANGRYWOLF(EntityType.WOLF),           ANGRYWOLVES(EntityType.WOLF),
    GIANT(EntityType.GIANT),              GIANTS(EntityType.GIANT),
    GHAST(EntityType.GHAST),              GHASTS(EntityType.GHAST),
    ENDERMAN(EntityType.ENDERMAN),        ENDERMEN(EntityType.ENDERMAN),
    CAVESPIDER(EntityType.CAVE_SPIDER),   CAVESPIDERS(EntityType.CAVE_SPIDER),
    SILVERFISH(EntityType.SILVERFISH),
    
    // 1.0 creatures
    BLAZE(EntityType.BLAZE),              BLAZES(EntityType.BLAZE),
    ENDERDRAGON(EntityType.ENDER_DRAGON), ENDERDRAGONS(EntityType.ENDER_DRAGON),
    SNOWMAN(EntityType.SNOWMAN),          SNOWMEN(EntityType.SNOWMAN),
    SNOWGOLEM(EntityType.SNOWMAN),        SNOWGOLEMS(EntityType.SNOWMAN),
    MUSHROOMCOW(EntityType.MUSHROOM_COW), MUSHROOMCOWS(EntityType.MUSHROOM_COW),
    VILLAGER(EntityType.VILLAGER),        VILLAGERS(EntityType.VILLAGER),
    
    // 1.2 creatures
    OCELOT(EntityType.OCELOT),            OCELOTS(EntityType.OCELOT),
    IRONGOLEM(EntityType.IRON_GOLEM),     IRONGOLEMS(EntityType.IRON_GOLEM),
    
    // Passive creatures
    CHICKEN(EntityType.CHICKEN),          CHICKENS(EntityType.CHICKEN),
    COW(EntityType.COW),                  COWS(EntityType.COW),
    PIG(EntityType.PIG),                  PIGS(EntityType.PIG),
    SHEEP(EntityType.SHEEP),
    SQUID(EntityType.SQUID),              SQUIDS(EntityType.SQUID),
    
    // Extended creatures
    EXPLODINGSHEEP(EntityType.SHEEP),
    
    // Slimes
    SLIME(EntityType.SLIME),              SLIMES(EntityType.SLIME),
    SLIMETINY(EntityType.SLIME),          SLIMESTINY(EntityType.SLIME),
    SLIMESMALL(EntityType.SLIME),         SLIMESSMALL(EntityType.SLIME),
    SLIMEBIG(EntityType.SLIME),           SLIMESBIG(EntityType.SLIME),
    SLIMEHUGE(EntityType.SLIME),          SLIMESHUGE(EntityType.SLIME),
    
    // Magma cubes
    MAGMACUBE(EntityType.MAGMA_CUBE),     MAGMACUBES(EntityType.MAGMA_CUBE),
    MAGMACUBETINY(EntityType.MAGMA_CUBE), MAGMACUBESTINY(EntityType.MAGMA_CUBE),
    MAGMACUBESMALL(EntityType.MAGMA_CUBE),MAGMACUBESSMALL(EntityType.MAGMA_CUBE),
    MAGMACUBEBIG(EntityType.MAGMA_CUBE),  MAGMACUBESBIG(EntityType.MAGMA_CUBE),
    MAGMACUBEHUGE(EntityType.MAGMA_CUBE), MAGMACUBESHUGE(EntityType.MAGMA_CUBE),
        
    // 1.4 creatures
    BAT(EntityType.BAT),                  BATS(EntityType.BAT),
    WITCH(EntityType.WITCH),              WITCHES(EntityType.WITCH),
    WITHER(EntityType.WITHER),            WITHERS(EntityType.WITHER),
    WITHERSKELETON(EntityType.SKELETON),  WITHERSKELETONS(EntityType.SKELETON),
    BABYZOMBIE(EntityType.ZOMBIE),        BABYZOMBIES(EntityType.ZOMBIE),
    BABYPIGMAN(EntityType.PIG_ZOMBIE),    BABYPIGMEN(EntityType.PIG_ZOMBIE),
    ZOMBIEVILLAGER(EntityType.ZOMBIE),    ZOMBIEVILLAGERS(EntityType.ZOMBIE),
    BABYZOMBIEVILLAGER(EntityType.ZOMBIE),BABYZOMBIEVILLAGERS(EntityType.ZOMBIE),
    // 1.6 creatures
    HORSE(EntityType.HORSE),              HORSES(EntityType.HORSE),
    DONKEY(EntityType.HORSE),             DONKEYS(EntityType.HORSE),
    MULE(EntityType.HORSE),               MULES(EntityType.HORSE),
    SKELETONHORSE(EntityType.HORSE),      SKELETONHORSES(EntityType.HORSE),
    UNDEADHORSE(EntityType.HORSE),        UNDEADHORSES(EntityType.HORSE);
    private List<DyeColor> colors = Arrays.asList(DyeColor.values());
    private EntityType type;
    
    private MACreature(EntityType type) {
        this.type = type;
    }
    
    public EntityType getType() {
        return type;
    }
    
    public static MACreature fromString(String string) {
        return WaveUtils.getEnumFromString(MACreature.class, string.replaceAll("[-_\\.]", ""));
    }
    
    public LivingEntity spawn(Arena arena, World world, Location loc) {
        LivingEntity e = (LivingEntity) world.spawnEntity(loc, type);
        e.getEquipment().clear();
        
        switch (this) {
            case SHEEP:
                ((Sheep) e).setColor(colors.get(MobArena.random.nextInt(colors.size())));
                break;
            case EXPLODINGSHEEP:
                arena.getMonsterManager().addExplodingSheep(e);
                ((Sheep) e).setColor(DyeColor.RED);
                break;
            case POWEREDCREEPERS:
                ((Creeper) e).setPowered(true);
                break;
            case ANGRYWOLVES:
                ((Wolf) e).setAngry(true);
                break;
            case SLIME:
            case SLIMES:
            case MAGMACUBE:
            case MAGMACUBES:
                ((Slime) e).setSize( (1 + MobArena.random.nextInt(3)) );
                break;
            case SLIMETINY:
            case SLIMESTINY:
            case MAGMACUBETINY:
            case MAGMACUBESTINY:
                ((Slime) e).setSize(1);
                break;
            case SLIMESMALL:
            case SLIMESSMALL:
            case MAGMACUBESMALL:
            case MAGMACUBESSMALL:
                ((Slime) e).setSize(2);
                break;
            case SLIMEBIG:
            case SLIMESBIG:
            case MAGMACUBEBIG:
            case MAGMACUBESBIG:
                ((Slime) e).setSize(3);
                break;
            case SLIMEHUGE:
            case SLIMESHUGE:
            case MAGMACUBEHUGE:
            case MAGMACUBESHUGE:
                ((Slime) e).setSize(4);
                break;
            case SKELETON:
            case SKELETONS:
                ((Skeleton) e).getEquipment().setItemInHand(new ItemStack(Material.BOW, 1));
            	break;
            case ZOMBIEPIGMAN:
            case ZOMBIEPIGMEN:
            	((PigZombie) e).getEquipment().setItemInHand(new ItemStack(Material.GOLD_SWORD, 1));
            	break;
            case ZOMBIEVILLAGER:
            case ZOMBIEVILLAGERS:
                ((Zombie) e).setVillager(true);
                break;
            case BABYZOMBIEVILLAGER:
            case BABYZOMBIEVILLAGERS:
                ((Zombie) e).setVillager(true);
            case BABYZOMBIE:
            case BABYZOMBIES:
            case BABYPIGMAN:
            case BABYPIGMEN:
                ((Zombie) e).setBaby(true);
                break;
            case WITHERSKELETON:
            case WITHERSKELETONS:
                ((Skeleton) e).getEquipment().setItemInHand(new ItemStack(Material.STONE_SWORD, 1));
                ((Skeleton) e).setSkeletonType(SkeletonType.WITHER);
                break;
            case HORSE:
            case HORSES:
                ((Horse) e).setVariant(Horse.Variant.HORSE);
                break;
            case DONKEY:
            case DONKEYS:
                ((Horse) e).setVariant(Horse.Variant.DONKEY);
                break;
            case MULE:
            case MULES:
                ((Horse) e).setVariant(Horse.Variant.MULE);
                break;
            case SKELETONHORSE:
            case SKELETONHORSES:
                ((Horse) e).setVariant(Horse.Variant.SKELETON_HORSE);
                break;
            case UNDEADHORSE:
            case UNDEADHORSES:
                ((Horse) e).setVariant(Horse.Variant.UNDEAD_HORSE);
                break;
            default:
                break;
        }
        
        if (e instanceof Creature) {


Please complete the code given below. 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace MUOViewer
{
	public enum FileID
	{
		Map0_mul = 0x00000000,
		StaIdx0_mul = 0x00000001,
		Statics0_mul = 0x00000002,
		ArtIdx_mul = 0x00000003,
		Art_mul = 0x00000004,
		Anim_idx = 0x00000005,
		Anim_mul = 0x00000006,
		SoundIdx_mul = 0x00000007,
		Sound_mul = 0x00000008,
		TexIdx_mul = 0x00000009,
		TexMaps_mul = 0x0000000A,
		GumpIdx_mul = 0x0000000B,
		GumpArt_mul = 0x0000000C,
		Multi_idx = 0x0000000D,
		Multi_mul = 0x0000000E,
		Skills_idx = 0x0000000F,
		Skills_mul = 0x00000010,
		TileData_mul = 0x00000011,
		AnimData_mul = 0x00000012,
		Hues_mul = 0x00000013,
	}
	public enum ExtendedFileID : int//Fucking UOG had to go and fuck up the MUO
	{
		Map0_mul = 0x00000040,
		StaIdx0_mul = 0x00000041,
		Statics0_mul = 0x00000042,
		ArtIdx_mul = 0x00000043,
		Art_mul = 0x00000044,
		Anim_idx = 0x00000045,
		Anim_mul = 0x00000046,
		SoundIdx_mul = 0x00000047,
		Sound_mul = 0x00000048,
		TexIdx_mul = 0x00000049,
		TexMaps_mul = 0x0000004A,
		GumpIdx_mul = 0x0000004B,
		GumpArt_mul = 0x0000004C,
		Multi_idx = 0x0000004D,
		Multi_mul = 0x0000004E,
	}
	public partial class MainForm : Form
	{
		private PatchFile _patchFile;
		private bool _updateScreen = true;
		private Animation _anim;
		public PatchFile patchFile { get { return _patchFile; } set { _patchFile = value;} }
		private void UpdateForm()
		{
			upDown.Maximum = _patchFile.patchCount - 1;
			nameLbl.Text = "Name: " + _patchFile.name;
			authLbl.Text = "Author: " + _patchFile.author;
			descLbl.Text = "Description: " + _patchFile.desc;
			patchesLbl.Text = "Patches: " + _patchFile.patchCount.ToString("0,0");
			Patch p = _patchFile.patches[(int)upDown.Value];
			UpdateImage(p);		
			if( p.data != null )
				textBox.Lines = FormatString(p.data, p.data.Length);
			fileidLbl.Text = "FileID: " + p.fileID.ToString("X2");
			blockidLbl.Text = "BlockID: " + p.blockID.ToString("X2");
			extraLbl.Text = "Extra: " + p.extra.ToString("X2");
			lengthLbl.Text = "Length: " + p.length.ToString();
			Invalidate();	
		}
		public MainForm()
		{
			InitializeComponent();
		}
		private void openToolStripMenuItem_Click(object sender, EventArgs e)
		{
			openFileDialog.Title = "Select a file to open";
			openFileDialog.CheckFileExists = false;
			if( openFileDialog.ShowDialog() == DialogResult.OK )
			{
				BinaryReader reader = new BinaryReader(File.OpenRead(openFileDialog.FileName));
				_patchFile = new PatchFile();
				int read = reader.ReadInt32();
				if( read != 0x504f554d )
				{
					MessageBox.Show("Invalid MUO file");
					return;
				}
				reader.ReadInt32();
				string temp = "";
				byte b = 0;
				while( ( b = reader.ReadByte() ) != 0 )
					temp = temp + ( (char)b );
				_patchFile.name = temp;
				temp = "";
				while( ( b = reader.ReadByte() ) != 0 )
				{
					temp = temp + ( (char)b );
				}
				_patchFile.desc = temp;
				temp = "";
				while( ( b = reader.ReadByte() ) != 0 )
				{
					temp = temp + ( (char)b );
				}
				_patchFile.author = temp;
				int count = reader.ReadInt32();
				_patchFile.patchCount = count;
				_patchFile.patches = new Patch[count];
				for( int i = 0; i < count; i++ )
				{
					Patch patch = new Patch();
					patch.fileID = reader.ReadInt32();
					patch.blockID = reader.ReadInt32();
					patch.extra = reader.ReadInt32();
					patch.length = reader.ReadInt32();
					if (patch.length > 0)
						patch.data = reader.ReadBytes(patch.length);
					else
					{
						patch.length = 0;
						patch.data = new byte[0];
					}
					_patchFile.patches[i] = patch;
				}
				if( reader.BaseStream.Length != reader.BaseStream.Position )
					MessageBox.Show("More Data!");
				UpdateForm(); 
			}
		}
		private string[] FormatString(byte[] buffer, int length)
		{
			List<string> output = new List<string>();
			output.Add("        0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F");
			output.Add("       -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --");
			int byteIndex = 0;
			int whole = length >> 4;
			int rem = length & 0xF;
			for( int i = 0; i < whole; ++i, byteIndex += 16 )
			{
				StringBuilder bytes = new StringBuilder(49);
				StringBuilder chars = new StringBuilder(16);
				for( int j = 0; j < 16; ++j )
				{
					int c = buffer[( i * 16 ) + j];
					bytes.Append(c.ToString("X2"));
					if( j != 7 )
						bytes.Append(' ');
					else
						bytes.Append("  ");
					if( c >= 0x20 && c < 0x80 )
						chars.Append((char)c);
					else
						chars.Append('.');
				}
				output.Add(byteIndex.ToString("X4") + "   " + bytes.ToString() + "  " + chars.ToString());
			}
			if( rem != 0 )
			{
				StringBuilder bytes = new StringBuilder(49);
				StringBuilder chars = new StringBuilder(rem);
				for( int j = 0; j < 16; ++j )
				{
					if( j < rem )
					{
						int c = buffer[j];
						bytes.Append(c.ToString("X2"));
						if( j != 7 )
							bytes.Append(' ');
						else
							bytes.Append("  ");
						if( c >= 0x20 && c < 0x80 )
							chars.Append((char)c);
						else
							chars.Append('.');
					}
					else
						bytes.Append("   ");
				}
				output.Add(byteIndex.ToString("X4") + "   " + bytes.ToString() + "  " + chars.ToString());
			}
			string[] realOutput = new string[output.Count];
			for( int i = 0; i < realOutput.Length; i++ )
				realOutput[i] = output[i].ToString();		
			return realOutput;
		}
		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Close();
		}		
		
		private byte[] GetData(byte[] p, out int length)
		{
			int sec = (int)secUpDown.Value;
			if( p.Length / 512 < secUpDown.Value && p.Length % 512 == 0 )
				sec = p.Length / 512;
			if (sec < 0)
			{
				secUpDown.Maximum = 0;
				_updateScreen = false;
				secUpDown.Value = 0;
				_updateScreen = true;
				sec = 0;
			}
			else
			{
				secUpDown.Maximum = p.Length % 512 == 0 ? p.Length / 512 - 1 : p.Length / 512;
				_updateScreen = false;
				secUpDown.Value = sec;
				_updateScreen = true;
			}
			length = Math.Min(512, p.Length - ( sec * 512 ));
			byte[] data = new byte[512];
			for( int i = 0; i < length; i++ )
				data[i] = p[i + sec * 512];
			return data;
		}
		private void upDown_ValueChanged(object sender, EventArgs e)
		{
			Patch p = _patchFile.patches[(int)upDown.Value];
			int length;
			UpdateImage(p);		
			textBox.Lines = FormatString(GetData(p.data, out length), length);
			fileidLbl.Text = "FileID: " + p.fileID.ToString("X2");
			blockidLbl.Text = "BlockID: " + p.blockID.ToString("X2");
			extraLbl.Text = "Extra: " + p.extra.ToString("X2");
			lengthLbl.Text = "Length: " + p.length.ToString();
			Invalidate();
		}
		private void UpdateImage(Patch p)
		{
			if( _anim != null )
				_anim.Stop();
			switch( p.fileID )
			{
				case (int)FileID.GumpArt_mul:
				{
					pictureBox1.BackgroundImage = GetGump(p);
					break;
				}
			case (int)FileID.Art_mul:
				{
					if (p.blockID > 0x3FFF)
						pictureBox1.BackgroundImage = LoadStatic(new MemoryStream(p.data));
					else
						pictureBox1.BackgroundImage = LoadLand(new MemoryStream(p.data));
					break;
				}
			case (int)FileID.Anim_mul:
				{
					_anim = new Animation(pictureBox1, p);					
					break;
				}
			case (int)ExtendedFileID.GumpArt_mul:
				{
					pictureBox1.BackgroundImage = GetGump(p);
					break;
				}
			case (int)ExtendedFileID.Art_mul:
				{
					try
					{
						pictureBox1.BackgroundImage = LoadLand(new MemoryStream(p.data));
					}
					catch
					{
						pictureBox1.BackgroundImage = LoadStatic(new MemoryStream(p.data));
					}
					break;
				}
			case (int)ExtendedFileID.Anim_mul:
				{
					_anim = new Animation(pictureBox1, p);
					break;
				}
				default:
				{
					pictureBox1.BackgroundImage = null;
					break;
				}
			}
		}
		private void secUpDown_ValueChanged(object sender, EventArgs e)
		{
			if( !_updateScreen )
				return;
			int length;
			Patch p = _patchFile.patches[(int)upDown.Value];
			textBox.Lines = FormatString(GetData(p.data, out length), length);
		}
		public unsafe static Bitmap GetGump(Patch p)
		{
			int length = p.length;
			int extra = p.extra;			
			int width = ( extra >> 16 ) & 0xFFFF;
			int height = extra & 0xFFFF;
			Bitmap bmp = new Bitmap(width, height, PixelFormat.Format16bppArgb1555);
			BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format16bppArgb1555);
			MemoryStream ms = new MemoryStream(p.data);
			BinaryReader bin = new BinaryReader(ms);
			int[] lookups = new int[height];
			int start = (int)bin.BaseStream.Position;
			for( int i = 0; i < height; ++i )
				lookups[i] = start + ( bin.ReadInt32() * 4 );
			ushort* line = (ushort*)bd.Scan0;
			int delta = bd.Stride >> 1;
			for( int y = 0; y < height; ++y, line += delta )
			{
				bin.BaseStream.Seek(lookups[y], SeekOrigin.Begin);
				ushort* cur = line;
				ushort* end = line + bd.Width;
				while( cur < end )
				{
					ushort color = bin.ReadUInt16();
					ushort* next = cur + bin.ReadUInt16();
					if( color == 0 )
					{
						cur = next;
					}
					else
					{
						color ^= 0x8000;
						while( cur < next )
							*cur++ = color;
					}
				}
			}
			bmp.UnlockBits(bd);
			bin.Close();
			return bmp;
		}
		private static unsafe Bitmap LoadStatic(Stream stream)
		{
			BinaryReader bin = new BinaryReader(stream);
			bin.ReadInt32();
			int width = bin.ReadInt16();
			int height = bin.ReadInt16();
			if( width <= 0 || height <= 0 )
				return null;
			int[] lookups = new int[height];
			int start = (int)bin.BaseStream.Position + ( height * 2 );
			for( int i = 0; i < height; ++i )
				lookups[i] = (int)( start + ( bin.ReadUInt16() * 2 ) );
			Bitmap bmp = new Bitmap(width, height, PixelFormat.Format16bppArgb1555);
			BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format16bppArgb1555);


Please complete the code given below. 
using System;
using Server.Targeting;
using Server.Items;
using Server.Network;
using Server.Multis;
using Server.Hiding.hide;
using Scripts.Skills.Utility.Hiding;
namespace Server.SkillHandlers
{
	public class Hiding
	{
        private static bool m_CombatOverride;
        private static Timer timer;
        public static bool CombatOverride
		{
			get{ return m_CombatOverride; }
			set{ m_CombatOverride = value; }
		}
        public long m_StartHiding { get; set; }
        public static void Initialize()
		{
			SkillInfo.Table[21].Callback = new SkillUseCallback( OnUse );
		}
        private class HideTimer : Timer
        {
            private Mobile m;
            TimeSpan returnTimer;
            private int counter = 0;
            public HideTimer(Mobile m, TimeSpan delay) : base(delay, delay, 3)
            {
                this.m = m;
                Priority = TimerPriority.TwoFiftyMS;
            }
            
            protected override void OnTick()
            {
                if (m == null || m.Deleted)
                {
                    this.Stop();
                    return;
                }
                if (m.Spell != null)
                {
                    m.SendLocalizedMessage(501238); // You are busy doing something else and cannot hide.
                    this.Stop();
                    return;
                }
                if (Core.ML && m.Target != null)
                {
                    Targeting.Target.Cancel(m);
                }
                double bonus = 0.0;
                BaseHouse house = BaseHouse.FindHouseAt(m);
                if (house != null && house.IsFriend(m))
                {
                    bonus = 100.0;
                }
                else if (!Core.AOS)
                {
                    if (house == null)
                        house = BaseHouse.FindHouseAt(new Point3D(m.X - 1, m.Y, 127), m.Map, 16);
                    if (house == null)
                        house = BaseHouse.FindHouseAt(new Point3D(m.X + 1, m.Y, 127), m.Map, 16);
                    if (house == null)
                        house = BaseHouse.FindHouseAt(new Point3D(m.X, m.Y - 1, 127), m.Map, 16);
                    if (house == null)
                        house = BaseHouse.FindHouseAt(new Point3D(m.X, m.Y + 1, 127), m.Map, 16);
                    if (house != null)
                        bonus = 50.0;
                }
                //int range = 18 - (int)(m.Skills[SkillName.Hiding].Value / 10);
                int range = Math.Min((int)((100 - m.Skills[SkillName.Hiding].Value) / 2) + 8, 18);  //Cap of 18 not OSI-exact, intentional difference
                bool badCombat = (!m_CombatOverride && m.Combatant != null && m.InRange(m.Combatant.Location, range) && m.Combatant.InLOS(m));
                bool ok = (!badCombat /*&& m.CheckSkill( SkillName.Hiding, 0.0 - bonus, 100.0 - bonus )*/ );
                /* old hiding system
                if ( ok )
                {
                    if ( !m_CombatOverride )
                    {
                        foreach ( Mobile check in m.GetMobilesInRange( range ) )
                        {
                            if ( check.InLOS( m ) && check.Combatant == m )
                            {
                                badCombat = true;
                                ok = false;
                                break;
                            }
                        }
                    }
                    ok = ( !badCombat && m.CheckSkill( SkillName.Hiding, 0.0 - bonus, 100.0 - bonus ) );
                }
                */
                //check if mobile is in warmode
                if (ok)
                {
                    if (!m_CombatOverride)
                    {
                        if (m.Warmode == true)
                        {
                            badCombat = true;
                            ok = false;
                        }
                    }
                    ok = (!badCombat && m.CheckSkill(SkillName.Hiding, 0.0 - bonus, 100.0 - bonus));
                }
                if (badCombat)
                {
                    m.RevealingAction();
                    m.LocalOverheadMessage(MessageType.Regular, 0x22, 501237); // You can't seem to hide right now.
                    Stop();
                    return;
                }
                else
                {
                    if (ok)
                    {
                        /*
                        m.Hidden = true;
                        m.Warmode = false;
                        m.LocalOverheadMessage(MessageType.Regular, 0x1F4, 501240); // You have hidden yourself well.
                        */
                    }
                    else
                    {
                        m.RevealingAction();
                        m.LocalOverheadMessage(MessageType.Regular, 0x22, 501241); // You can't seem to hide here.
                    }
                    Stop();
                    return;
                }
            }
            public void Tick()
            {
                OnTick();
            }
        }
        public static TimeSpan OnUse( Mobile m )
		{
            
            Hide hide = new HidingHide(m);
            hide.TryToHide();
            return TimeSpan.FromSeconds(0.25);
		}
        private class HidingHide : Hide
        {
            private Mobile m;
            public HidingHide( Mobile m ) : base( m )
            {
                this.m = m;
            }
            public override void OnHide()
            {
                if (m.Spell != null)
                {
                    m.SendLocalizedMessage(501238); // You are busy doing something else and cannot hide.
                }
                if (Core.ML && m.Target != null)
                {
                    Targeting.Target.Cancel(m);
                }
                double bonus = 0.0;
                BaseHouse house = BaseHouse.FindHouseAt(m);
                if (house != null && house.IsFriend(m))
                {
                    bonus = 100.0;
                }
                else if (!Core.AOS)
                {
                    if (house == null)
                        house = BaseHouse.FindHouseAt(new Point3D(m.X - 1, m.Y, 127), m.Map, 16);
                    if (house == null)
                        house = BaseHouse.FindHouseAt(new Point3D(m.X + 1, m.Y, 127), m.Map, 16);
                    if (house == null)
                        house = BaseHouse.FindHouseAt(new Point3D(m.X, m.Y - 1, 127), m.Map, 16);


Please complete the code given below. 
#region License
// Copyright (c) 2013, ClearCanvas Inc.
// All rights reserved.
// http://www.ClearCanvas.ca
//
// This file is part of the ClearCanvas RIS/PACS open source project.
//
// The ClearCanvas RIS/PACS open source project is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// The ClearCanvas RIS/PACS open source project is distributed in the hope that it
// will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// the ClearCanvas RIS/PACS open source project.  If not, see
// <http://www.gnu.org/licenses/>.
#endregion
#if	UNIT_TESTS
#pragma warning disable 1591,0419,1574,1587
using System;
using System.Collections.Generic;
using Macro.Common.Utilities;
using Macro.Dicom;
using Macro.Dicom.Iod;
using Macro.ImageViewer.StudyManagement;
using NUnit.Framework;
namespace Macro.ImageViewer.AdvancedImaging.Fusion.Tests
{
	[TestFixture]
	public class FusionDisplaySetFactoryTests
	{
		[Test]
		public void TestNullCreation()
		{
			var factory = new PETFusionDisplaySetFactory(PETFusionType.CT);
			var displaySets = CreateDisplaySets(factory, Combine<ISopDataSource>());
			try
			{
				Assert.IsEmpty(displaySets, "Display set factories should not throw an exception if there is nothing to create.");
			}
			finally
			{
				Dispose(displaySets);
			}
		}
		[Test]
		public void TestPETAndCTFusion()
		{
			var factory = new PETFusionDisplaySetFactory(PETFusionType.CT);
			var seriesCT = CreateSopSeries(25, "PatientA", "StudyA", "SeriesCT", 1, "FrameA", Modality.CT);
			var seriesPET = CreateSopSeries(25, "PatientA", "StudyA", "SeriesPET", 2, "FrameA", Modality.PT);
			var displaySets = CreateDisplaySets(factory, Combine(seriesCT, seriesPET));
			try
			{
				Assert.IsNotEmpty(displaySets, "Fusion display sets should be created for trivially simple PET-CT data.");
			}
			finally
			{
				Dispose(displaySets);
				Dispose(seriesCT, seriesPET);
			}
		}
		[Test]
		public void TestNoFusingWrongModality()
		{
			var factory = new PETFusionDisplaySetFactory(PETFusionType.CT);
			var seriesMR = CreateSopSeries(25, "PatientA", "StudyA", "SeriesMR", 1, "FrameA", Modality.MR);
			var seriesPET = CreateSopSeries(25, "PatientA", "StudyA", "SeriesPET", 2, "FrameA", Modality.PT);
			var displaySets = CreateDisplaySets(factory, Combine(seriesMR, seriesPET));
			try
			{
				Assert.IsEmpty(displaySets, "Fusion display sets should not be created for PET-MR using a PET-CT factory.");
			}
			finally
			{
				Dispose(displaySets);
				Dispose(seriesMR, seriesPET);
			}
		}
		[Test]
		public void TestNoFusingInvalidModalities()
		{
			var factory = new PETFusionDisplaySetFactory(PETFusionType.CT);
			var seriesCT = CreateSopSeries(25, "PatientA", "StudyA", "SeriesCT", 1, "FrameA", Modality.CT);
			var seriesMR = CreateSopSeries(25, "PatientA", "StudyA", "SeriesMR", 1, "FrameA", Modality.MR);
			var displaySets = CreateDisplaySets(factory, Combine(seriesCT, seriesMR));
			try
			{
				Assert.IsEmpty(displaySets, "Fusion display sets should not be created between invalid modalities (e.g. CT and MR).");
			}
			finally
			{
				Dispose(displaySets);
				Dispose(seriesCT, seriesMR);
			}
		}
		[Test]
		public void TestNoFusingDifferentStudies()
		{
			var factory = new PETFusionDisplaySetFactory(PETFusionType.CT);
			var seriesCT = CreateSopSeries(25, "PatientA", "StudyA", "SeriesCT", 1, "FrameA", Modality.CT);
			var seriesPET = CreateSopSeries(25, "PatientA", "StudyB", "SeriesPET", 2, "FrameA", Modality.PT);
			var displaySets = CreateDisplaySets(factory, Combine(seriesCT, seriesPET));
			try
			{
				Assert.IsEmpty(displaySets, "Fusion display sets should not be created for series in different studies.");
			}
			finally
			{
				Dispose(displaySets);
				Dispose(seriesCT, seriesPET);
			}
		}
		[Test]
		public void TestNoFusingDifferentPatients()
		{
			var factory = new PETFusionDisplaySetFactory(PETFusionType.CT);
			var seriesCT = CreateSopSeries(25, "PatientA", "StudyA", "SeriesCT", 1, "FrameA", Modality.CT);
			var seriesPET = CreateSopSeries(25, "PatientB", "StudyB", "SeriesPET", 2, "FrameA", Modality.PT);
			var displaySets = CreateDisplaySets(factory, Combine(seriesCT, seriesPET));
			try
			{
				Assert.IsEmpty(displaySets, "Fusion display sets should not be created for series from different patients.");
			}
			finally
			{
				Dispose(displaySets);
				Dispose(seriesCT, seriesPET);
			}
		}
		[Test]
		public void TestFusingDifferentFramesOfReference()
		{
			var factory = new PETFusionDisplaySetFactory(PETFusionType.CT);
			var seriesCT = CreateSopSeries(25, "PatientA", "StudyA", "SeriesCT", 1, "FrameA", Modality.CT);
			var seriesPET = CreateSopSeries(25, "PatientA", "StudyA", "SeriesPET", 2, "FrameB", Modality.PT);
			var displaySets = CreateDisplaySets(factory, Combine(seriesCT, seriesPET));
			try
			{
				Assert.IsNotEmpty(displaySets, "Fusion display sets should still be created even with different frames of reference.");
			}
			finally
			{
				Dispose(displaySets);
				Dispose(seriesCT, seriesPET);
			}
		}
		[Test]
		public void TestPETFusionDisplaySetDescriptor()
		{
			StudyTree studyTree;
			var factory = new PETFusionDisplaySetFactory(PETFusionType.CT);
			var seriesCT = CreateSopSeries(25, "PatientA", "StudyA", "SeriesCT", 1, "FrameA", Modality.CT);
			var seriesPET = CreateSopSeries(25, "PatientA", "StudyA", "SeriesPET", 2, "FrameA", Modality.PT);
			var seriesPETCor = CreateSopSeries(25, "PatientA", "StudyA", "SeriesPETCor", 3, "FrameA", Modality.PT, true, false);
			var displaySets = CreateDisplaySets(factory, Combine(seriesCT, seriesPET, seriesPETCor), out studyTree);
			try
			{
				Assert.AreEqual(2, displaySets.Count, "There is only one valid combination of fuseable series.");
				// Verify identity of fused series
				var displaySet = CollectionUtils.SelectFirst(displaySets, d => ValidateFusionDisplaySetDescriptor(d.Descriptor, HashUid("SeriesCT"), HashUid("SeriesPET")));
				Assert.IsNotNull(displaySet, "Could not find the uncorrected fusion series.");
				Assert.IsFalse(((PETFusionDisplaySetDescriptor) displaySet.Descriptor).AttenuationCorrection, "Uncorrected fusion series is incorrectly flagged as corrected.");
				var displaySetCor = CollectionUtils.SelectFirst(displaySets, d => ValidateFusionDisplaySetDescriptor(d.Descriptor, HashUid("SeriesCT"), HashUid("SeriesPETCor")));
				Assert.IsNotNull(displaySetCor, "Could not find the corrected fusion series.");
				Assert.IsTrue(((PETFusionDisplaySetDescriptor) displaySetCor.Descriptor).AttenuationCorrection, "Corrected fusion series is incorrectly flagged as uncorrected.");
				var seriesCollection = CollectionUtils.FirstElement(CollectionUtils.FirstElement(studyTree.Patients).Studies).Series;
				var ctSeries = CollectionUtils.SelectFirst(seriesCollection, s => s.SeriesDescription == "SeriesCT");
				var petSeries = CollectionUtils.SelectFirst(seriesCollection, s => s.SeriesDescription == "SeriesPET");
				var petCorSeries = CollectionUtils.SelectFirst(seriesCollection, s => s.SeriesDescription == "SeriesPETCor");
				var expectedDescriptor = GetFusedDisplaySetName(ctSeries, petSeries, false);
				var expectedDescriptorCor = GetFusedDisplaySetName(ctSeries, petCorSeries, true);
				// Validate the names of the display sets (this is what is shown on the context menu)
				Assert.AreEqual(expectedDescriptor, displaySet.Name, "Name string differs for uncorrected display set.");
				Assert.AreEqual(expectedDescriptorCor, displaySetCor.Name, "Name string differs for corrected display set.");
			}
			catch (Exception)
			{
				if (displaySets.Count > 0)
				{
					Console.WriteLine("Generated Display Sets ({0})", displaySets.Count);
					foreach (var displaySet in displaySets)


Please complete the code given below. 
import os
import warnings
import numpy as np
from photon_tools.io import timetag_parse, pt2_parse, metadata
time_ch_dtype = np.dtype([('time', 'u8'), ('chan', 'u1')])
def verify_monotonic(times, filename):
    """ Verify that timestamps are monotonically increasing """
    if len(times) == 0: return
    negatives = times[1:] <= times[:-1]
    if np.count_nonzero(negatives) > 0:
        indices = np.nonzero(negatives)
        warnings.warn('%s: Found %d non-monotonic timestamps: photon indices %s' %
                      (filename, np.count_nonzero(negatives), indices))
def verify_continuity(times, filename, gap_factor=1000):
    """ Search for improbably long gaps in the photon stream """
    if len(times) == 0: return
    tau = (times[-1] - times[0]) / len(times)
    gaps = (times[1:] - times[:-1]) > gap_factor*tau
    if np.count_nonzero(gaps) > 0:
        msg = '%s: Found %d large gaps:\n' % (filename, np.count_nonzero(gaps))
        gap_starts, = np.nonzero(gaps)
        for s in gap_starts:
            msg += '    starting at %10d, ending at %10d, lasting %10d' % \
                   (times[s], times[s+1], times[s+1] - times[s])
        warnings.warn(msg)
class InvalidChannel(ValueError):
    def __init__(self, requested_channel, valid_channels=[]):
        self.requested_channel = requested_channel
        self.valid_channels = valid_channels
    def __str__(self):
        return "Channel %s was requested but this file type only supports channels %s." \
            % (self.requested_channel, self.valid_channels)
class TimestampFile(object):
    """
    Represents a timestamp file.
    A timestamp file is a file containing a sequential set of integer
    photon arrival timestamps taken in one or more channels.
    """
    def __init__(self, filename, jiffy, valid_channels=None):
        if valid_channels is None:
            valid_channels = self.__class__.valid_channels
        self._valid_channels = valid_channels
        self._fname = filename
        self._jiffy = jiffy
    @classmethod
    def extensions(self):
        """
        A list of supported file extensions
        """
        return []
    @property
    def jiffy(self):
        """
        The timestamp resolution in seconds or ``None`` is unknown.
        :returns: float
        """
        return self._jiffy
    @property
    def valid_channels(self):
        """
        The names of the channels of the file.
        Note that not all of these will have timestamps.
        :returns: list
        """
        return self._valid_channels
    @property
    def metadata(self):
        """
        Metadata describing the data set.
        :returns: dictionary mapping string metadata names to values
        """
        return self._metadata
    @property
    def name(self):
        """ File name of timestamp file """
        return self._fname
    def timestamps(self):
        """
        Read the timestamp data for all channels of the file
        :returns: An array of dtype :var:`time_ch_dtype` containing monotonically
        increasing timestamps annotated with channel numbers.
        """
        data = self._read_all()
        verify_monotonic(data['time'], self._fname)
        verify_continuity(data['time'], self._fname)
        return data
    def channel(self, channel):
        """
        Read photon data for a channel of the file
        :type channel: A valid channel name from :func:`valid_channels`.
        :returns: An array of ``u8`` timestamps.
        """
        self._validate_channel(channel)
        data = self._read_channel(channel)
        verify_monotonic(data, self._fname)
        verify_continuity(data, self._fname)
        return data
    def _read_all(self):
        """ Read the timestamps for all channels """
        raise NotImplementedError()
    def _read_channel(self, channel):
        """ Actually read the data of a channel """
        raise NotImplementedError()
    def _validate_channel(self, channel):
        """ A utility for implementations """
        if channel not in self.valid_channels:
            raise InvalidChannel(channel, self.valid_channels)
class PicoquantFile(TimestampFile):
    """ A Picoquant PT2 and PT3 timestamp file """
    valid_channels = [0,1,2,3]
    extensions = ['pt2', 'pt3']
    def __init__(self, fname):
        # TODO: Read metadata
        TimestampFile.__init__(self, fname, jiffy=4e-12)
    def _read_all(self):
        raise NotImplementedError()
    def _read_channel(self, channel):
        return pt2_parse.read_pt2(self._fname, channel)
class TimetagFile(TimestampFile):
    """ A timestamp file from the Goldner lab FPGA timetagger """
    extensions = ['timetag']
    valid_channels = [0,1,2,3]
    def __init__(self, fname):
        TimestampFile.__init__(self, fname, jiffy = None)
        self._metadata = metadata.get_metadata(fname)
        if self.metadata is not None:
            self._jiffy = 1. / self.metadata['clockrate']
        if not os.path.isfile(fname):
            raise IOError("File %s does not exist" % fname)
    def _read_all(self):
        res = timetag_parse.get_strobe_events(self._fname, 0xf)
        res.dtype.names = time_ch_dtype.names
        return res
    def _read_channel(self, channel):
        return timetag_parse.get_strobe_events(self._fname, 1<<channel)['t']
class RawFile(TimestampFile):
    """ Raw unsigned 64-bit timestamps """
    extensions = ['times']
    valid_channels = [0]
    def __init__(self, fname):
        TimestampFile.__init__(self, fname, jiffy = None)
    def _read_all(self):
        timestamps = np.fromfile(self._fname, dtype='u8')
        return np.from_records([timestamps, np.zeros_like(timestamps, dtype='u1')],
                               dtype=time_ch_dtype)
    def _read_channel(self, channel):
        return np.fromfile(self._fname, dtype='u8')
class RawChFile(TimestampFile):
    """ Raw unsigned 64-bit timestamps, followed by 8-bit channel number """
    extensions = ['timech']
    valid_channels = range(256)
    def __init__(self, fname):
        TimestampFile.__init__(self, fname, jiffy = None)
    def _read_all(self):
        return np.fromfile(self._fname, dtype=time_ch_dtype)
    def _read_channel(self, channel):
        d = self._read_all()
        return d[d['chan'] == channel]['time']
readers = [
    PicoquantFile,
    TimetagFile,
    RawFile,
    RawChFile,
]
def supported_extensions():
    """
    A dictionary mapping supported file extensions to their associated
    :class:`TimestampFile` class.
    """
    extensions = {}
    for reader in readers:
        for ext in reader.extensions:
            extensions[ext] = reader
    return extensions
def find_reader(fname):


Please complete the code given below. 
/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: CellChangeJobs.java
 *
 * Copyright (c) 2006 Sun Microsystems and Static Free Software
 *
 * Electric(tm) is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Electric(tm) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Electric(tm); see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, Mass 02111-1307, USA.
 */
package com.sun.electric.tool.user;
import com.sun.electric.database.IdMapper;
import com.sun.electric.database.ImmutableArcInst;
import com.sun.electric.database.geometry.EGraphics;
import com.sun.electric.database.geometry.EPoint;
import com.sun.electric.database.geometry.GenMath;
import com.sun.electric.database.geometry.Orientation;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.Export;
import com.sun.electric.database.hierarchy.Library;
import com.sun.electric.database.hierarchy.View;
import com.sun.electric.database.id.CellId;
import com.sun.electric.database.prototype.NodeProto;
import com.sun.electric.database.text.Name;
import com.sun.electric.database.topology.ArcInst;
import com.sun.electric.database.topology.Geometric;
import com.sun.electric.database.topology.NodeInst;
import com.sun.electric.database.topology.PortInst;
import com.sun.electric.database.variable.ElectricObject;
import com.sun.electric.database.variable.TextDescriptor;
import com.sun.electric.database.variable.UserInterface;
import com.sun.electric.technology.ArcProto;
import com.sun.electric.technology.technologies.Artwork;
import com.sun.electric.technology.technologies.Generic;
import com.sun.electric.tool.Job;
import com.sun.electric.tool.JobException;
import com.sun.electric.tool.user.ui.EditWindow;
import com.sun.electric.tool.user.ui.WindowContent;
import com.sun.electric.tool.user.ui.WindowFrame;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
 * Class for Jobs that make changes to the cells.
 */
public class CellChangeJobs
{
	// constructor, never used
	private CellChangeJobs() {}
	/****************************** DELETE A CELL ******************************/
	/**
	 * Class to delete a cell in a new thread.
	 */
	public static class DeleteCell extends Job
	{
		Cell cell;
		public DeleteCell(Cell cell)
		{
			super("Delete " + cell, User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);
			this.cell = cell;
			startJob();
		}
		public boolean doIt() throws JobException
		{
			// check cell usage once more
			if (cell.isInUse("delete", false, true)) return false;
			cell.kill();
			return true;
		}
	}
	/**
	 * This class implement the command to delete a list of cells.
	 */
	public static class DeleteManyCells extends Job
	{
		private List<Cell> cellsToDelete;
		public DeleteManyCells(List<Cell> cellsToDelete)
		{
			super("Delete Multiple Cells", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);
			this.cellsToDelete = cellsToDelete;
			startJob();
		}
		public boolean doIt() throws JobException
		{
			// iteratively delete, allowing cells in use to be deferred
			boolean didDelete = true;
			while (didDelete)
			{
				didDelete = false;
				for (int i=0; i<cellsToDelete.size(); i++)
				{
					Cell cell = cellsToDelete.get(i);
					// if the cell is in use, defer
					if (cell.isInUse(null, true, true)) continue;
					// cell not in use: remove it from the list and delete it
					cellsToDelete.remove(i);
					i--;
					System.out.println("Deleting " + cell);
					cell.kill();
					didDelete = true;
				}
			}
			// warn about remaining cells that were in use
			for(Cell cell : cellsToDelete)
				cell.isInUse("delete", false, true);
			return true;
		}
		public void terminateOK()
		{
			System.out.println("Deleted " + cellsToDelete.size() + " cells");
			EditWindow.repaintAll();
		}
	}
	/****************************** RENAME CELLS ******************************/
	/**
	 * Class to rename a cell in a new thread.
	 */
	public static class RenameCell extends Job
	{
		private Cell cell;
		private String newName;
		private String newGroupCell;
		private IdMapper idMapper;
		public RenameCell(Cell cell, String newName, String newGroupCell)
		{
			super("Rename " + cell, User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);
			this.cell = cell;
			this.newName = newName;
			this.newGroupCell = newGroupCell;
			startJob();
		}
		public boolean doIt() throws JobException
		{
			idMapper = cell.rename(newName, newGroupCell);
			fieldVariableChanged("idMapper");
			return true;
		}
		public void terminateOK()
		{
			User.fixStaleCellReferences(idMapper);
		}
	}
	/**
	 * Class to rename a cell in a new thread.
	 */
	public static class DeleteCellGroup extends Job
	{
		List<Cell> cells;
		public DeleteCellGroup(Cell.CellGroup group)
		{
			super("Delete Cell Group", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);
			cells = new ArrayList<Cell>();
			for(Iterator<Cell> it = group.getCells(); it.hasNext(); )
			{
				cells.add(it.next());
			}
			startJob();
		}
		public boolean doIt() throws JobException
		{
			for(Cell cell : cells)
			{
				// Doesn't check cells in the same group
				// check cell usage once more
				if (cell.isInUse("delete", false, false))
					return false;
			}
			// Now real delete
			for(Cell cell : cells)
			{
				cell.kill();
			}
			return true;
		}
	}
	/**
	 * Class to rename a cell in a new thread.
	 */
	public static class RenameCellGroup extends Job
	{
		Cell cellInGroup;
		String newName;
		public RenameCellGroup(Cell cellInGroup, String newName)
		{
			super("Rename Cell Group", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);
			this.cellInGroup = cellInGroup;
			this.newName = newName;
			startJob();
		}
		public boolean doIt() throws JobException
		{
			// see if all cells in the group have the same name
			boolean allSameName = true;
			String lastName = null;
			for(Iterator<Cell> it = cellInGroup.getCellGroup().getCells(); it.hasNext(); )
			{
				String cellName = it.next().getName();
				if (lastName != null && !lastName.equals(cellName))
				{
					allSameName = false;
					break;
				}
				lastName = cellName;
			}
			List<Cell> cells = new ArrayList<Cell>();
			for(Iterator<Cell> it = cellInGroup.getCellGroup().getCells(); it.hasNext(); )
				cells.add(it.next());
			String newGroupCell = null;
			for(Cell cell : cells)
			{
				if (allSameName)
				{
					cell.rename(newName, newName);
				} else
				{
					if (newGroupCell == null)
					{
						System.out.println("Renaming is not possible because cells in group don't have same root name.");
						System.out.println("'" + newName + "' was added as prefix.");
						newGroupCell = newName + cell.getName();
					}
					cell.rename(newName+cell.getName(), newGroupCell);
				}
			}
			return true;
		}
	}
	/****************************** SHOW CELLS GRAPHICALLY ******************************/
	/**
	 * This class implement the command to make a graph of the cells.
	 */
	public static class GraphCells extends Job
	{
		private static final double TEXTHEIGHT = 2;
		private Cell top;
		private Cell graphCell;
		private static class GraphNode
		{
			String    name;
			int       depth;
			int       clock;
			double    x, y;
			double    yoff;
			NodeInst  pin;
			NodeInst  topPin;
			NodeInst  botPin;
			GraphNode main;
		}
		public GraphCells(Cell top)
		{
			super("Graph Cells", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);
			this.top = top;
			startJob();
		}
		public boolean doIt() throws JobException
		{
			// create the graph cell
			graphCell = Cell.newInstance(Library.getCurrent(), "CellStructure");
			fieldVariableChanged("graphCell");
			if (graphCell == null) return false;
			if (graphCell.getNumVersions() > 1)
				System.out.println("Creating new version of cell: " + graphCell.getName()); else
					System.out.println("Creating cell: " + graphCell.getName());
			// create GraphNodes for every cell and initialize the depth to -1
			Map<Cell,GraphNode> graphNodes = new HashMap<Cell,GraphNode>();
			for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); )
			{
				Library lib = it.next();
				if (lib.isHidden()) continue;
				for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); )
				{
					Cell cell = cIt.next();
					GraphNode cgn = new GraphNode();
					cgn.name = cell.describe(false);
					cgn.depth = -1;
					graphNodes.put(cell, cgn);
				}
			}
			// find all top-level cells
			int maxDepth = 0;
			if (top != null)
			{
				GraphNode cgn = graphNodes.get(top);
				cgn.depth = 0;
			} else
			{
				for(Iterator<Cell> cIt = Library.getCurrent().getCells(); cIt.hasNext(); )
				{
					Cell cell = cIt.next();
					if (cell.getNumUsagesIn() == 0)
					{
						GraphNode cgn = graphNodes.get(cell);
						cgn.depth = 0;
					}
				}
			}
			double xScale = 2.0 / 3.0;
			double yScale = 20;
			double yOffset = TEXTHEIGHT * 1.25;
			double maxWidth = 0;
			// now place all cells at their proper depth
			boolean more = true;
			while (more)
			{
				more = false;
				for(Iterator<Library> it = Library.getLibraries(); it.hasNext(); )
				{
					Library lib = it.next();
					if (lib.isHidden()) continue;
					for(Iterator<Cell> cIt = lib.getCells(); cIt.hasNext(); )
					{
						Cell cell = cIt.next();


Please complete the code given below. 
/* 
    Z80 Virtual Machine
    Copyright (C) 2008 - 2012 Leonid Gordo
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
namespace Z80VM
{
    public partial class Form1 : Form
    {
       public Bitmap bmp = new Bitmap(256, 192);
        
        public Form1()
        {
            InitializeComponent();
            pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;
            ClientSize = new Size(256 * 2 + 80, 192 * 2 + 80);
            pictureBox1.Size = new Size(256 * 2, 192 * 2);
            resize();
            if (Program.size == 48)
            {
                k48ToolStripMenuItem.Checked = true;
                k128ToolStripMenuItem.Checked = false;
            }
            else
            {
                k48ToolStripMenuItem.Checked = false;
                k128ToolStripMenuItem.Checked = true;
            }
            pictureBox1.BackgroundImage = bmp;
        }
        public void SetImage()
        {
           // this.pictureBox1.BackgroundImage = this.bmp;
            pictureBox1.Refresh();
        }
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }
        private void OnClose(object sender, FormClosingEventArgs e)
        {
            Program.go = false;
        }
        private void OnKeyPress(object sender, KeyPressEventArgs e)
        {
        }
        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            int keyCode = (int)e.KeyCode;
            int shift = (int)e.KeyData / 0x10000;
            if ((shift & 4) != 0) return;
            doKey(true, keyCode, (short)shift);
        }
        public bool doKey(bool down, int ascii, short mods)
        {
		
            bool CAPS, SYMB;
		
		    CAPS = (mods & 1) != 0;
		    SYMB = (mods & 2) != 0;
    		
		    // Change control versions of keys to lower case
		    if ((ascii >= 1) & (ascii <= 0x27) & SYMB)
			    ascii = ascii + 97 - 1;
    		
    		
		    if (CAPS) Program.keyCAPS_V = (Program.keyCAPS_V & (~1)); else Program.keyCAPS_V = (Program.keyCAPS_V | 1);
		    if (SYMB) Program.keyB_SPC = (Program.keyB_SPC & (~2)); else Program.keyB_SPC = (Program.keyB_SPC | 2);
    		
		    switch(ascii) {
			    case 8: // Backspace
				    if (down) {
					    Program.key6_0 = (Program.key6_0 & (~ 1));
					    Program.keyCAPS_V = (Program.keyCAPS_V & (~ 1));
				    }else {
					    Program.key6_0 = (Program.key6_0 | 1);
					    if (!CAPS)
						    Program.keyCAPS_V = (Program.keyCAPS_V | 1);					
				    }
                    break;
			    case 65: // A
				    if (down) Program.keyA_G = (Program.keyA_G & (~ 1)); else Program.keyA_G = (Program.keyA_G | 1);
                    break;
			    case 66: // B
				    if (down )  Program.keyB_SPC = (Program.keyB_SPC & (~ 16)) ; else Program.keyB_SPC = (Program.keyB_SPC | 16);
                    break;
			    case 67: // C
				    if (down )  Program.keyCAPS_V = (Program.keyCAPS_V & (~ 8)) ; else Program.keyCAPS_V = (Program.keyCAPS_V | 8);
                    break;
			    case 68: // D
				    if (down )  Program.keyA_G = (Program.keyA_G & (~ 4)) ; else Program.keyA_G = (Program.keyA_G | 4);
                    break;
			    case 69: // E
				    if (down )  Program.keyQ_T = (Program.keyQ_T & (~ 4)) ; else Program.keyQ_T = (Program.keyQ_T | 4);
                    break;
			    case 70: // F
				    if (down )  Program.keyA_G = (Program.keyA_G & (~ 8)) ; else Program.keyA_G = (Program.keyA_G | 8);
                    break;
			    case 71: // G
				    if (down )  Program.keyA_G = (Program.keyA_G & (~ 16)) ; else Program.keyA_G = (Program.keyA_G | 16);
                    break;
			    case 72: // H
				    if (down )  Program.keyH_ENT = (Program.keyH_ENT & (~ 16)) ; else Program.keyH_ENT = (Program.keyH_ENT | 16);
                    break;
			    case 73: // I
				    if (down )  Program.keyY_P = (Program.keyY_P & (~ 4)) ; else Program.keyY_P = (Program.keyH_ENT | 4);
                    break;
			    case 74: // J
				    if (down )  Program.keyH_ENT = (Program.keyH_ENT & (~ 8)) ; else Program.keyH_ENT = (Program.keyH_ENT | 8);
                    break;
			    case 75: // K
				    if (down )  Program.keyH_ENT = (Program.keyH_ENT & (~ 4)) ; else Program.keyH_ENT = (Program.keyH_ENT | 4);
                    break;
			    case 76: // L
				    if (down )  Program.keyH_ENT = (Program.keyH_ENT & (~ 2)) ; else Program.keyH_ENT = (Program.keyH_ENT | 2);
                    break;
			    case 77: // M
				    if (down )  Program.keyB_SPC = (Program.keyB_SPC & (~ 4)) ; else Program.keyB_SPC = (Program.keyB_SPC | 4);
                    break;
			    case 78: // N
				    if (down )  Program.keyB_SPC = (Program.keyB_SPC & (~ 8)) ; else Program.keyB_SPC = (Program.keyB_SPC | 8);
                    break;
			    case 79: // O
				    if (down )  Program.keyY_P = (Program.keyY_P & (~ 2)) ; else Program.keyY_P = (Program.keyY_P | 2);
                    break;
			    case 80: // P
				    if (down )  Program.keyY_P = (Program.keyY_P & (~ 1)) ; else Program.keyY_P = (Program.keyY_P | 1);
                    break;
			    case 81: // Q
				    if (down )  Program.keyQ_T = (Program.keyQ_T & (~ 1)) ; else Program.keyQ_T = (Program.keyQ_T | 1);
                    break;
			    case 82: // R
				    if (down )  Program.keyQ_T = (Program.keyQ_T & (~ 8)) ; else Program.keyQ_T = (Program.keyQ_T | 8);
                    break;
			    case 83: // S
				    if (down )  Program.keyA_G = (Program.keyA_G & (~ 2)) ; else Program.keyA_G = (Program.keyA_G | 2);
                    break;
			    case 84: // T
				    if (down )  Program.keyQ_T = (Program.keyQ_T & (~ 16)) ; else Program.keyQ_T = (Program.keyQ_T | 16);
                    break;
			    case 85: // U
				    if (down )  Program.keyY_P = (Program.keyY_P & (~ 8)) ; else Program.keyY_P = (Program.keyY_P | 8);
                    break;
			    case 86: // V
				    if (down )  Program.keyCAPS_V = (Program.keyCAPS_V & (~ 16)) ; else Program.keyCAPS_V = (Program.keyCAPS_V | 16);
                    break;
			    case 87: // W
				    if (down )  Program.keyQ_T = (Program.keyQ_T & (~ 2)) ; else Program.keyQ_T = (Program.keyQ_T | 2);
                    break;
			    case 88: // X
				    if (down )  Program.keyCAPS_V = (Program.keyCAPS_V & (~ 4)) ; else Program.keyCAPS_V = (Program.keyCAPS_V | 4);
                    break;
			    case 90: // Y
				    if (down )  Program.keyCAPS_V = (Program.keyCAPS_V & (~ 2)) ; else Program.keyCAPS_V = (Program.keyCAPS_V | 2);
                    break;
			    case 89: // Z
				    if (down )  Program.keyY_P = (Program.keyY_P & (~ 16)) ; else Program.keyY_P = (Program.keyY_P | 16);
                    break;
			    case 48: // 0
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 1)) ; else Program.key6_0 = (Program.key6_0 | 1);
                    break;
			    case 49: // 1
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 1)) ; else Program.key1_5 = (Program.key1_5 | 1);
                    break;
			    case 50: // 2
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 2)) ; else Program.key1_5 = (Program.key1_5 | 2);
                    break;
			    case 51: // 3
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 4)) ; else Program.key1_5 = (Program.key1_5 | 4);
                    break;
			    case 52: // 4
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 8)) ; else Program.key1_5 = (Program.key1_5 | 8);
                    break;
			    case 53: // 5
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 16)) ; else Program.key1_5 = (Program.key1_5 | 16);
                    break;
			    case 54: // 6
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 16)) ; else Program.key6_0 = (Program.key6_0 | 16);
                    break;
			    case 55: // 7
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 8)) ; else Program.key6_0 = (Program.key6_0 | 8);
                    break;
			    case 56: // 8
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 4)) ; else Program.key6_0 = (Program.key6_0 | 4);
                    break;
			    case 57: // 9
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 2)) ; else Program.key6_0 = (Program.key6_0 | 2);
                    break;
			    case 96: // Keypad 0
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 1)) ; else Program.key6_0 = (Program.key6_0 | 1);
                    break;
			    case 97: // Keypad 1
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 1)) ; else Program.key1_5 = (Program.key1_5 | 1);
                    break;
			    case 98: // Keypad 2
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 2)) ; else Program.key1_5 = (Program.key1_5 | 2);
                    break;
			    case 99: // Keypad 3
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 4)) ; else Program.key1_5 = (Program.key1_5 | 4);
                    break;
			    case 100: // Keypad 4
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 8)) ; else Program.key1_5 = (Program.key1_5 | 8);
                    break;
			    case 101: // Keypad 5
				    if (down )  Program.key1_5 = (Program.key1_5 & (~ 16)) ; else Program.key1_5 = (Program.key1_5 | 16);
                    break;
			    case 102: // Keypad 6
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 16)) ; else Program.key6_0 = (Program.key6_0 | 16);
                    break;
			    case 103: // Keypad 7
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 8)) ; else Program.key6_0 = (Program.key6_0 | 8);
                    break;
			    case 104: // Keypad 8
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 4)) ; else Program.key6_0 = (Program.key6_0 | 4);
                    break;
			    case 105: // Keypad 9
				    if (down )  Program.key6_0 = (Program.key6_0 & (~ 2)) ; else Program.key6_0 = (Program.key6_0 | 2);
                    break;
			    case 106: // Keypad *
				    if (down ) 
					    Program.keyB_SPC = (Program.keyB_SPC & ~(18));
				    else
					    if (SYMB ) 
						    Program.keyB_SPC = (Program.keyB_SPC | 16);
					    else
						    Program.keyB_SPC = (Program.keyB_SPC | 18);
                    break;
			    case 107: // Keypad +
                    if (down)
                    {
                        Program.keyH_ENT = (Program.keyH_ENT & (~4));
                        Program.keyB_SPC = (Program.keyB_SPC & (~2));
                    }
                    else
                    {
                        Program.keyH_ENT = (Program.keyH_ENT | 4);
                        if (!SYMB)
                            Program.keyB_SPC = (Program.keyB_SPC | 2);
                    }
                        break;
			    case 109: // Keypad -
                    if (down)
                    {
                        Program.keyH_ENT = (Program.keyH_ENT & (~8));
                        Program.keyB_SPC = (Program.keyB_SPC & (~2));
                    }
                    else
                    {
                        Program.keyH_ENT = (Program.keyH_ENT | 8);
                        if (!SYMB)
                            Program.keyB_SPC = (Program.keyB_SPC | 2);
                    }
                        break;
			    case 110: // Keypad .
				    if (down ) 
					    Program.keyB_SPC = (Program.keyB_SPC & (~ 6));
				    else
					    if (SYMB ) 
						    Program.keyB_SPC = (Program.keyB_SPC | 4);
					     else
						    Program.keyB_SPC = (Program.keyB_SPC | 6);
                    break;
			    case 111: // Keypad /
                    if (down)
                    {
                        Program.keyCAPS_V = (Program.keyCAPS_V & (~16));
                        Program.keyB_SPC = (Program.keyB_SPC & (~2));
                    }
                    else
                    {
                        Program.keyCAPS_V = (Program.keyCAPS_V | 16);
                        if (!SYMB)
                            Program.keyB_SPC = (Program.keyB_SPC | 2);
                    }
                    break;
			    case 37: // Left
                    if (down)
                    {
                        Program.key1_5 = (Program.key1_5 & (~16));
                        Program.keyCAPS_V = (Program.keyCAPS_V & (~1));
                    }
                    else
                    {
                        Program.key1_5 = (Program.key1_5 | 16);
                        if (!SYMB)
                            Program.keyB_SPC = (Program.keyB_SPC | 2);
                    }
                    break;
			    case 38: // Up
                    if (down)
                    {
                        Program.key6_0 = (Program.key6_0 & (~8));
                        Program.keyCAPS_V = (Program.keyCAPS_V & (~1));
                    }
                    else
                    {
                        Program.key6_0 = (Program.key6_0 | 8);
                        if (!CAPS)
                            Program.keyCAPS_V = (Program.keyCAPS_V | 1);
                    }
                    break;
			    case 39: // Right
                    if (down)
                    {
                        Program.key6_0 = (Program.key6_0 & (~4));
                        Program.keyCAPS_V = (Program.keyCAPS_V & (~1));
                    }
                    else
                    {
                        Program.key6_0 = (Program.key6_0 | 4);
                        if (!CAPS)
                            Program.keyCAPS_V = (Program.keyCAPS_V | 1);
                    }
                    break;
			    case 40: // Down
                    if (down)
                    {
                        Program.key6_0 = (Program.key6_0 & (~16));
                        Program.keyCAPS_V = (Program.keyCAPS_V & (~1));
                    }
                    else
                    {
                        Program.key6_0 = (Program.key6_0 | 16);
                        if (!CAPS)
                            Program.keyCAPS_V = (Program.keyCAPS_V | 1);
                    }
                    break;
			    case 13: // RETURN
				    if (down )  Program.keyH_ENT = (Program.keyH_ENT & (~ 1)) ; else Program.keyH_ENT = (Program.keyH_ENT | 1);
                    break;
			    case 32: // SPACE BAR
				    if (down )  Program.keyB_SPC = (Program.keyB_SPC & (~ 1)) ; else Program.keyB_SPC = (Program.keyB_SPC | 1);
                    break;
			    case 187: // =/+ key
				    if (down ) {
                        if (CAPS)
                            Program.keyH_ENT = (Program.keyH_ENT & (~4));
                        else
                        {
                            Program.keyH_ENT = (Program.keyH_ENT & (~2));
                            Program.keyB_SPC = (Program.keyB_SPC & (~2));
                            Program.keyCAPS_V = (Program.keyCAPS_V | 1);
                        }
                    }
				    else {
					    Program.keyH_ENT = (Program.keyH_ENT | 4);
					    Program.keyH_ENT = (Program.keyH_ENT | 2);
					    Program.keyB_SPC = (Program.keyB_SPC | 2);
				    }
                    break;


Please complete the code given below. 
#!/usr/bin/env python3
"""Compute the auto and cross-correlation of delta fields for a list of IGM
absorption.
This module follow the procedure described in sections 4.3 of du Mas des
Bourboux et al. 2020 (In prep) to compute the distortion matrix
"""
import time
import argparse
import multiprocessing
from multiprocessing import Pool, Lock, cpu_count, Value
from functools import partial
import numpy as np
import fitsio
from picca import constants, cf, utils, io
from picca.utils import userprint
def calc_metal_dmat(abs_igm1, abs_igm2, healpixs):
    """Computes the metal distortion matrix.
    To optimize the computation, first compute a list of neighbours for each of
    the healpix. This is an auxiliar function to split the computational load
    using several CPUs.
    Args:
        abs_igm1: str
            Name of the absorption in picca.constants defining the
            redshift of the forest pixels
        abs_igm2: str
            Name of the second absorption in picca.constants defining the
            redshift of the forest pixels
        healpixs: array of ints
            List of healpix numbers
    Returns:
        The distortion matrix data
    """
    cf.fill_neighs(healpixs)
    np.random.seed(healpixs[0])
    dmat_data = cf.compute_metal_dmat(healpixs,
                                      abs_igm1=abs_igm1,
                                      abs_igm2=abs_igm2)
    return dmat_data
def main():
    # pylint: disable-msg=too-many-locals,too-many-branches,too-many-statements
    """Compute the auto and cross-correlation of delta fields for a list of IGM
    absorption."""
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description=('Compute the auto and cross-correlation of delta fields '
                     'for a list of IGM absorption.'))
    parser.add_argument('--out',
                        type=str,
                        default=None,
                        required=True,
                        help='Output file name')
    parser.add_argument('--in-dir',
                        type=str,
                        default=None,
                        required=True,
                        help='Directory to delta files')
    parser.add_argument('--in-dir2',
                        type=str,
                        default=None,
                        required=False,
                        help='Directory to 2nd delta files')
    parser.add_argument('--rp-min',
                        type=float,
                        default=0.,
                        required=False,
                        help='Min r-parallel [h^-1 Mpc]')
    parser.add_argument('--rp-max',
                        type=float,
                        default=200.,
                        required=False,
                        help='Max r-parallel [h^-1 Mpc]')
    parser.add_argument('--rt-max',
                        type=float,
                        default=200.,
                        required=False,
                        help='Max r-transverse [h^-1 Mpc]')
    parser.add_argument('--np',
                        type=int,
                        default=50,
                        required=False,
                        help='Number of r-parallel bins')
    parser.add_argument('--nt',
                        type=int,
                        default=50,
                        required=False,
                        help='Number of r-transverse bins')
    parser.add_argument(
        '--coef-binning-model',
        type=int,
        default=1,
        required=False,
        help=('Coefficient multiplying np and nt to get finner binning for the '
              'model'))
    parser.add_argument(
        '--z-cut-min',
        type=float,
        default=0.,
        required=False,
        help=('Use only pairs of forest x object with the mean of the last '
              'absorber redshift and the object redshift larger than '
              'z-cut-min'))
    parser.add_argument(
        '--z-cut-max',
        type=float,
        default=10.,
        required=False,
        help=('Use only pairs of forest x object with the mean of the last '
              'absorber redshift and the object redshift smaller than '
              'z-cut-max'))
    parser.add_argument(
        '--lambda-abs',
        type=str,
        default='LYA',
        required=False,
        help=('Name of the absorption in picca.constants defining the redshift '
              'of the delta'))
    parser.add_argument(
        '--lambda-abs2',
        type=str,
        default=None,
        required=False,
        help=('Name of the absorption in picca.constants defining the redshift '
              'of the 2nd delta'))
    parser.add_argument(
        '--abs-igm',
        type=str,
        default=[],
        required=False,
        nargs='*',
        help=('List of names of metal absorption in picca.constants present in '
              'forest'))
    parser.add_argument(
        '--abs-igm2',
        type=str,
        default=[],
        required=False,
        nargs='*',
        help=('List of names of metal absorption in picca.constants present in '
              '2nd forest'))
    parser.add_argument('--z-ref',
                        type=float,
                        default=2.25,
                        required=False,
                        help='Reference redshift')
    parser.add_argument(
        '--z-evol',
        type=float,
        default=2.9,
        required=False,
        help='Exponent of the redshift evolution of the delta field')
    parser.add_argument(
        '--z-evol2',
        type=float,
        default=2.9,
        required=False,
        help='Exponent of the redshift evolution of the 2nd delta field')
    parser.add_argument(
        '--metal-alpha',
        type=float,
        default=1.,
        required=False,
        help='Exponent of the redshift evolution of the metal delta field')
    parser.add_argument(
        '--fid-Om',
        type=float,
        default=0.315,
        required=False,
        help='Omega_matter(z=0) of fiducial LambdaCDM cosmology')
    parser.add_argument(
        '--fid-Or',
        type=float,
        default=0.,
        required=False,
        help='Omega_radiation(z=0) of fiducial LambdaCDM cosmology')
    parser.add_argument('--fid-Ok',
                        type=float,
                        default=0.,
                        required=False,
                        help='Omega_k(z=0) of fiducial LambdaCDM cosmology')
    parser.add_argument(
        '--fid-wl',
        type=float,
        default=-1.,
        required=False,
        help='Equation of state of dark energy of fiducial LambdaCDM cosmology')
    parser.add_argument(
        '--remove-same-half-plate-close-pairs',
        action='store_true',
        required=False,
        help='Reject pairs in the first bin in r-parallel from same half plate')
    parser.add_argument(
        '--rej',
        type=float,
        default=1.,
        required=False,
        help=('Fraction of rejected forest-forest pairs: -1=no rejection, '
              '1=all rejection'))
    parser.add_argument('--nside',
                        type=int,
                        default=16,
                        required=False,
                        help='Healpix nside')
    parser.add_argument('--nproc',
                        type=int,
                        default=None,
                        required=False,
                        help='Number of processors')
    parser.add_argument('--nspec',
                        type=int,
                        default=None,
                        required=False,
                        help='Maximum number of spectra to read')
    parser.add_argument(
        '--unfold-cf',
        action='store_true',
        required=False,
        help=('rp can be positive or negative depending on the relative '
              'position between absorber1 and absorber2'))
    args = parser.parse_args()
    if args.nproc is None:
        args.nproc = cpu_count() // 2
    userprint("nproc", args.nproc)
    # setup variables in module cf
    cf.r_par_max = args.rp_max
    cf.r_trans_max = args.rt_max
    cf.r_par_min = args.rp_min
    cf.z_cut_max = args.z_cut_max
    cf.z_cut_min = args.z_cut_min
    cf.num_bins_r_par = args.np * args.coef_binning_model
    cf.num_bins_r_trans = args.nt * args.coef_binning_model
    cf.num_model_bins_r_par = args.np * args.coef_binning_model
    cf.num_model_bins_r_trans = args.nt * args.coef_binning_model
    cf.nside = args.nside
    cf.z_ref = args.z_ref
    cf.alpha = args.z_evol
    cf.reject = args.rej
    cf.lambda_abs = constants.ABSORBER_IGM[args.lambda_abs]
    cf.remove_same_half_plate_close_pairs = args.remove_same_half_plate_close_pairs
    cf.alpha_abs = {}
    cf.alpha_abs[args.lambda_abs] = cf.alpha
    for metal in args.abs_igm:
        cf.alpha_abs[metal] = args.metal_alpha
    # load fiducial cosmology
    cf.cosmo = constants.Cosmo(Om=args.fid_Om,
                               Or=args.fid_Or,
                               Ok=args.fid_Ok,
                               wl=args.fid_wl)
    t0 = time.time()
    ### Read data 1
    data, num_data, z_min, z_max = io.read_deltas(args.in_dir,
                                                  cf.nside,
                                                  cf.lambda_abs,
                                                  cf.alpha,
                                                  cf.z_ref,
                                                  cf.cosmo,
                                                  max_num_spec=args.nspec)
    del z_max
    cf.data = data
    cf.num_data = num_data
    cf.ang_max = utils.compute_ang_max(cf.cosmo, cf.r_trans_max, z_min)
    userprint("")
    userprint("done, npix = {}".format(len(data)))
    ### Read data 2
    if args.in_dir2 or args.lambda_abs2:
        if args.lambda_abs2 or args.unfold_cf:
            cf.x_correlation = True
        cf.alpha2 = args.z_evol2
        if args.in_dir2 is None:
            args.in_dir2 = args.in_dir
        if args.lambda_abs2:
            cf.lambda_abs2 = constants.ABSORBER_IGM[args.lambda_abs2]
        else:
            cf.lambda_abs2 = cf.lambda_abs
        cf.alpha_abs[args.lambda_abs2] = cf.alpha2
        for m in args.abs_igm2:
            cf.alpha_abs[m] = args.metal_alpha
        data2, num_data2, z_min2, z_max2 = io.read_deltas(
            args.in_dir2,
            cf.nside,
            cf.lambda_abs2,
            cf.alpha2,
            cf.z_ref,
            cf.cosmo,
            max_num_spec=args.nspec)
        del z_max2
        cf.data2 = data2
        cf.num_data2 = num_data2
        cf.ang_max = utils.compute_ang_max(cf.cosmo, cf.r_trans_max, z_min,
                                           z_min2)
        userprint("")
        userprint("done, npix = {}".format(len(data2)))
    t1 = time.time()
    userprint(f'picca_metal_dmat.py - Time reading data: {(t1-t0)/60:.3f} minutes')
    cf.counter = Value('i', 0)
    cf.lock = Lock()
    cpu_data = {}
    for index, healpix in enumerate(sorted(list(data.keys()))):
        num_processor = index % args.nproc
        if not num_processor in cpu_data:
            cpu_data[num_processor] = []
        cpu_data[num_processor].append(healpix)
    # intiialize arrays to store the results for the different metal absorption
    dmat_all = []
    weights_dmat_all = []
    r_par_all = []
    r_trans_all = []
    z_all = []
    names = []
    num_pairs_all = []
    num_pairs_used_all = []
    abs_igm = [args.lambda_abs] + args.abs_igm
    userprint("abs_igm = {}".format(abs_igm))
    if args.lambda_abs2 is None:
        args.lambda_abs2 = args.lambda_abs
        args.abs_igm2 = args.abs_igm
    abs_igm_2 = [args.lambda_abs2] + args.abs_igm2
    if cf.x_correlation:
        userprint("abs_igm2 = {}".format(abs_igm_2))
    # loop over metals
    for index1, abs_igm1 in enumerate(abs_igm):
        index0 = index1
        if args.lambda_abs != args.lambda_abs2:
            index0 = 0
        for index2, abs_igm2 in enumerate(abs_igm_2[index0:]):
            if index1 == 0 and index2 == 0:
                continue
            cf.counter.value = 0
            calc_metal_dmat_wrapper = partial(calc_metal_dmat, abs_igm1,
                                              abs_igm2)
            userprint("")
            # compute the distortion matrix
            if args.nproc > 1:
                context = multiprocessing.get_context('fork')
                pool = context.Pool(processes=args.nproc)
                dmat_data = pool.map(calc_metal_dmat_wrapper,
                                     sorted(cpu_data.values()))
                pool.close()
            elif args.nproc == 1:
                dmat_data = map(calc_metal_dmat_wrapper,
                                sorted(cpu_data.values()))
                dmat_data = list(dmat_data)
            # merge the results from different CPUs
            dmat_data = np.array(dmat_data)
            weights_dmat = dmat_data[:, 0].sum(axis=0)
            dmat = dmat_data[:, 1].sum(axis=0)
            r_par = dmat_data[:, 2].sum(axis=0)
            r_trans = dmat_data[:, 3].sum(axis=0)
            z = dmat_data[:, 4].sum(axis=0)
            weights = dmat_data[:, 5].sum(axis=0)
            num_pairs = dmat_data[:, 6].sum(axis=0)
            num_pairs_used = dmat_data[:, 7].sum(axis=0)
            # normalize_values
            w = weights > 0
            r_par[w] /= weights[w]
            r_trans[w] /= weights[w]
            z[w] /= weights[w]
            w = weights_dmat > 0
            dmat[w, :] /= weights_dmat[w, None]
            # add these results to the list ofor the different metal absorption
            dmat_all.append(dmat)
            weights_dmat_all.append(weights_dmat)
            r_par_all.append(r_par)
            r_trans_all.append(r_trans)
            z_all.append(z)
            names.append(abs_igm1 + "_" + abs_igm2)
            num_pairs_all.append(num_pairs)
            num_pairs_used_all.append(num_pairs_used)
    t2 = time.time()
    userprint(f'picca_metal_dmat.py - Time computing all metal matrices : {(t2-t1)/60:.3f} minutes')
    # save the results
    results = fitsio.FITS(args.out, 'rw', clobber=True)
    header = [
        {
            'name': 'RPMIN',
            'value': cf.r_par_min,
            'comment': 'Minimum r-parallel [h^-1 Mpc]'
        },
        {
            'name': 'RPMAX',
            'value': cf.r_par_max,
            'comment': 'Maximum r-parallel [h^-1 Mpc]'
        },
        {
            'name': 'RTMAX',
            'value': cf.r_trans_max,
            'comment': 'Maximum r-transverse [h^-1 Mpc]'
        },
        {
            'name': 'NP',
            'value': cf.num_bins_r_par,
            'comment': 'Number of bins in r-parallel'
        },
        {
            'name': 'NT',
            'value': cf.num_bins_r_trans,
            'comment': ' Number of bins in r-transverse'
        },
        {
            'name': 'COEFMOD',
            'value': args.coef_binning_model,
            'comment': 'Coefficient for model binning'
        },
        {
            'name': 'ZCUTMIN',
            'value': cf.z_cut_min,
            'comment': 'Minimum redshift of pairs'
        },
        {
            'name': 'ZCUTMAX',
            'value': cf.z_cut_max,
            'comment': 'Maximum redshift of pairs'
        },
        {
            'name': 'REJ',
            'value': cf.reject,
            'comment': 'Rejection factor'
        },
        {
            'name': 'ALPHAMET',
            'value': args.metal_alpha,
            'comment': 'Evolution of metal bias'
        }, {
            'name': 'OMEGAM',
            'value': args.fid_Om,
            'comment': 'Omega_matter(z=0) of fiducial LambdaCDM cosmology'
        }, {
            'name': 'OMEGAR',
            'value': args.fid_Or,
            'comment': 'Omega_radiation(z=0) of fiducial LambdaCDM cosmology'
        }, {
            'name': 'OMEGAK',
            'value': args.fid_Ok,
            'comment': 'Omega_k(z=0) of fiducial LambdaCDM cosmology'
        }, {
            'name': 'WL',
            'value': args.fid_wl,
            'comment': 'Equation of state of dark energy of fiducial LambdaCDM cosmology'
        }
        ]
    len_names = np.array([len(name) for name in names]).max()
    names = np.array(names, dtype='S' + str(len_names))
    results.write(
        [
            np.array(num_pairs_all),
            np.array(num_pairs_used_all),
            np.array(names)
        ],
        names=['NPALL', 'NPUSED', 'ABS_IGM'],
        header=header,
        comment=['Number of pairs', 'Number of used pairs', 'Absorption name'],
        extname='ATTRI')
    names = names.astype(str)
    out_list = []
    out_names = []
    out_comment = []
    out_units = []
    for index, name in enumerate(names):
        out_names += ['RP_' + name]
        out_list += [r_par_all[index]]
        out_comment += ['R-parallel']
        out_units += ['h^-1 Mpc']
        out_names += ['RT_' + name]
        out_list += [r_trans_all[index]]
        out_comment += ['R-transverse']
        out_units += ['h^-1 Mpc']
        out_names += ['Z_' + name]
        out_list += [z_all[index]]
        out_comment += ['Redshift']
        out_units += ['']
        out_names += ['DM_' + name]
        out_list += [dmat_all[index]]
        out_comment += ['Distortion matrix']
        out_units += ['']
        out_names += ['WDM_' + name]


Please complete the code given below. 
from enum import Enum
from collections import defaultdict
from pathlib import Path
from typing import Dict, List, Optional, TextIO, Union
import re
from .config import LIST_TYPE_TAGS, TAG_KEY_MAPPING, WOK_TAG_KEY_MAPPING, WOK_LIST_TYPE_TAGS
__all__ = ["load", "loads"]
class RisImplementation(Enum):
    BASE = "base"
    WOK = "wok"
class NextLine(Exception):
    pass
class Base:
    START_TAG: str = None
    END_TAG: str = "ER"
    IGNORE: List[str] = []
    PATTERN: str = None
    def __init__(self, lines, mapping, strict=True):
        self.lines = lines
        self.pattern = re.compile(self.PATTERN)
        self._mapping = mapping
        self.strict = strict
    @property
    def mapping(self):
        if self._mapping is not None:
            return self._mapping
        else:
            return self.default_mapping
    def parse(self):
        self.in_ref = False
        self.current = {}
        self.last_tag = None
        for line_number, line in enumerate(self.lines):
            if not line.strip():
                continue
            if self.is_tag(line):
                try:
                    yield self.parse_tag(line, line_number)
                    self.current = {}
                    self.in_ref = False
                    self.last_tag = None
                except NextLine:
                    continue
            else:
                try:
                    yield self.parse_other(line, line_number)
                except NextLine:
                    continue
    def parse_tag(self, line, line_number):
        tag = self.get_tag(line)
        if tag in self.IGNORE:
            raise NextLine
        if tag == self.END_TAG:
            return self.current
        if tag == self.START_TAG:
            # New entry
            if self.in_ref:
                raise IOError(f"Missing end of record tag in line {line_number}:\n {line}")
            self.add_tag(tag, line)
            self.in_ref = True
            raise NextLine
        if not self.in_ref:
            raise IOError(f"Invalid start tag in line {line_number}:\n {line}")
        if tag in self.mapping:
            self.add_tag(tag, line)
            raise NextLine
        else:
            self.add_unknown_tag(tag, line)
            raise NextLine
        raise NextLine
    def parse_other(self, line, line_number):
        if not self.strict:
            raise NextLine
        if self.in_ref:
            # Active reference
            if self.last_tag is None:
                raise IOError(f"Expected tag in line {line_number}:\n {line}")
            # Active tag
            self.add_tag(self.last_tag, line, all_line=True)
            raise NextLine
        if self.is_counter(line):
            raise NextLine
        raise IOError(f"Expected start tag in line {line_number}:\n {line}")
    def add_single_value(self, name, value, is_multi=False):
        if not is_multi:
            ignore_this_if_has_one = value
            self.current.setdefault(name, ignore_this_if_has_one)
            return
        value_must_exist_or_is_bug = self.current[name]
        self.current[name] = " ".join((value_must_exist_or_is_bug, value))
    def add_list_value(self, name, value):
        try:
            self.current[name].append(value)
        except KeyError:
            self.current[name] = [value]
    def add_tag(self, tag, line, all_line=False):
        self.last_tag = tag
        name = self.mapping[tag]
        if all_line:
            new_value = line.strip()
        else:
            new_value = self.get_content(line)
        if tag not in LIST_TYPE_TAGS:
            self.add_single_value(name, new_value, is_multi=all_line)
            return
        self.add_list_value(name, new_value)
    def add_unknown_tag(self, tag, line):
        name = self.mapping["UK"]
        tag = self.get_tag(line)
        value = self.get_content(line)
        # check if unknown_tag dict exists
        if name not in self.current:
            self.current[name] = defaultdict(list)
        self.current[name][tag].append(value)
    def get_tag(self, line):
        return line[0:2]
    def is_tag(self, line):
        return bool(self.pattern.match(line))
    def get_content(self, line):
        raise NotImplementedError
class Wok(Base):
    START_TAG = "PT"
    IGNORE = ["FN", "VR", "EF"]
    PATTERN = r"^[A-Z][A-Z0-9] |^ER\s?|^EF\s?"
    LIST_TYPE_TAGS = WOK_LIST_TYPE_TAGS
    default_mapping = WOK_TAG_KEY_MAPPING
    def get_content(self, line):
        return line[2:].strip()
    def is_counter(self, line):
        return True
class Ris(Base):
    START_TAG = "TY"
    PATTERN = r"^[A-Z][A-Z0-9]  - |^ER  -\s*$"
    default_mapping = TAG_KEY_MAPPING
    counter_re = re.compile("^[0-9]+.")
    def get_content(self, line):
        return line[6:].strip()
    def is_counter(self, line):
        none_or_match = self.counter_re.match(line)
        return bool(none_or_match)
def load(
    file: Union[TextIO, Path],
    mapping: Optional[Dict] = None,
    implementation: RisImplementation = RisImplementation.BASE,
    strict: bool = True,
) -> List[Dict]:
    """Load a RIS file and return a list of entries.
    Entries are codified as dictionaries whose keys are the
    different tags. For single line and singly occurring tags,
    the content is codified as a string. In the case of multiline
    or multiple key occurrences, the content is returned as a list
    of strings.
    Args:
        file (Union[TextIO, Path]): File handle to read ris formatted data.
        mapping (Dict, optional): a tag mapping dictionary.
        implementation (RisImplementation): RIS implementation; base by default.
        strict (bool): Boolean to allow non-tag data between records to be ignored.
    Returns:
        list: Returns list of RIS entries.
    """
    text = file.read_text() if isinstance(file, Path) else file.read()
    return list(loads(text, mapping, implementation, strict))
def loads(
    obj: str,
    mapping: Optional[Dict] = None,
    implementation: RisImplementation = RisImplementation.BASE,
    strict: bool = True,
) -> List[Dict]:
    """Load a RIS file and return a list of entries.
    Entries are codified as dictionaries whose keys are the
    different tags. For single line and singly occurring tags,
    the content is codified as a string. In the case of multiline
    or multiple key occurrences, the content is returned as a list
    of strings.
    Args:
        obj (str): A string version of an RIS file.
        mapping (Dict, optional): a tag mapping dictionary.
        implementation (RisImplementation): RIS implementation; base by default.
        strict (bool): Boolean to allow non-tag data between records to be ignored.
    Returns:
        list: Returns list of RIS entries.
    """
    # remove BOM if present


Please complete the code given below. 
/*
 * @copyright 2013 Philip Warner
 * @license GNU General Public License
 * 
 * This file is part of Book Catalogue.
 *
 * Book Catalogue is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Book Catalogue is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Book Catalogue.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.eleybourn.bookcatalogue.backup;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.eleybourn.bookcatalogue.BookCatalogueApp;
import com.eleybourn.bookcatalogue.CatalogueDBAdapter;
import com.eleybourn.bookcatalogue.backup.Importer.CoverFinder;
import com.eleybourn.bookcatalogue.utils.StorageUtils;
/**
 * Class to find covers for an importer when the import is reading from a local directory.
 * 
 * @author pjw
 */
public class LocalCoverFinder implements Importer.CoverFinder {
	/** The root path to search for files */
	private final String mSrc;
	private final String mDst;
	private final boolean mIsForeign;
	private final String mSharedStoragePath;
	private CatalogueDBAdapter mDbHelper;
	public LocalCoverFinder(String srcPath, String dstPath) {
		mSrc = srcPath;
		mDst = dstPath;
		mIsForeign = !mSrc.equals(mDst);
		mSharedStoragePath = StorageUtils.getSharedStorage().getAbsolutePath();
		mDbHelper = new CatalogueDBAdapter(BookCatalogueApp.context);
		mDbHelper.open();
	}
	
	public void copyOrRenameCoverFile(String srcUuid, long srcId, long dstId) throws IOException {
		if (srcUuid != null && !srcUuid.equals("")) {
			// Only copy UUID files if they are foreign...since they already exists, otherwise.
			if (mIsForeign)
				copyCoverImageIfMissing(srcUuid);							
		} else {
			if (srcId != 0) {
				// This will be a rename or a copy
				if (mIsForeign)
					copyCoverImageIfMissing(srcId, dstId);
				else
					renameCoverImageIfMissing(srcId, dstId);																
			}
		}
	}
	private File findExternalCover(String name) {
		// Find the original, if present.
		File orig = new File(mSrc + "/" + name + ".jpg");
		if (!orig.exists()) {
			orig = new File(mSrc + "/" + name + ".png");
		}
		// Nothing to copy?
		if (!orig.exists())
			return null;
		else
			return orig;
		
	}
	/**
	 * Find the current cover file (or new file) based on the passed source and UUID.
	 * 
	 * @param orig		Original file to be copied/renamed if no existing file.
	 * @param newUuid	UUID of file
	 * 
	 * @return			Existing file (if length > 0), or new file object
	 */
	private File getNewCoverFile(File orig, String newUuid) {
		File newFile;
		// Check for ANY current image; delete empty ones and retry
		newFile = CatalogueDBAdapter.fetchThumbnailByUuid(newUuid);
		while (newFile.exists()) {
			if (newFile.length() > 0)
				return newFile;
			else
				newFile.delete();
			newFile = CatalogueDBAdapter.fetchThumbnailByUuid(newUuid);
		}
		
		// Get the new path based on the input file type.
		if (orig.getAbsolutePath().toLowerCase().endsWith(".png")) 
			newFile = new File(mSharedStoragePath + "/" + newUuid + ".png");
		else
			newFile = new File(mSharedStoragePath + "/" + newUuid + ".jpg");
		return newFile;
	}
	/**
	 * Copy a specified source file into the default cover location for a new file.
	 * DO NO OVERWRITE EXISTING FILES.
	 * 
	 * @param orig
	 * @param newUuid
	 * @throws IOException
	 */
	private void copyFileToCoverImageIfMissing(File orig, String newUuid) throws IOException {
		// Nothing to copy?
		if (orig == null || !orig.exists() || orig.length() == 0)
			return;
		// Check for ANY current image
		File newFile = getNewCoverFile(orig, newUuid);
		if (newFile.exists())
			return;
		// Copy it.
		InputStream in = null;
		OutputStream out = null;
		try {
			// Open in & out
			in = new FileInputStream(orig);
			out = new FileOutputStream(newFile);
			// Get a buffer
			byte[] buffer = new byte[8192];
			int nRead = 0;
			// Copy
			while( (nRead = in.read(buffer)) > 0){
			    out.write(buffer, 0, nRead);
			}
			// Close both. We close them here so exceptions are signalled
			in.close();
			in = null;
			out.close();
			out = null;
		} finally {
			// If not already closed, close.
			try {
				if (in != null)
					in.close();
			} catch (Exception e) {};
			try {
				if (out != null)
					out.close();
			} catch (Exception e) {};
		}
	}
	/**
	 * Rename/move a specified source file into the default cover location for a new file.
	 * DO NO OVERWRITE EXISTING FILES.
	 * 
	 * @param orig
	 * @param newUuid
	 * @throws IOException
	 */
	private void renameFileToCoverImageIfMissing(File orig, String newUuid) throws IOException {
		// Nothing to copy?
		if (orig == null || !orig.exists() || orig.length() == 0)
			return;
		// Check for ANY current image
		File newFile = getNewCoverFile(orig, newUuid);
		if (newFile.exists())
			return;
		orig.renameTo(newFile);
	}
	/**
	 * Copy the ID-based cover from its current location to the correct location in shared 
	 * storage, if it exists.
	 * 
	 * @param externalId		The file ID in external media
	 * @param newId				The new file ID
	 * @throws IOException 
	 */
	private void renameCoverImageIfMissing(long externalId, long newId) throws IOException {
		File orig = findExternalCover(Long.toString(externalId));
		// Nothing to copy?
		if (orig == null || !orig.exists() || orig.length() == 0)
			return;
		String newUuid = mDbHelper.getBookUuid(newId);
		renameFileToCoverImageIfMissing(orig, newUuid);
	}
	/**
	 * Copy the ID-based cover from its current location to the correct location in shared 
	 * storage, if it exists.
	 * 
	 * @param externalId		The file ID in external media
	 * @param newId				The new file ID
	 * @throws IOException 
	 */
	private void copyCoverImageIfMissing(long externalId, long newId) throws IOException {
		File orig = findExternalCover(Long.toString(externalId));
		// Nothing to copy?


Please complete the code given below. 
package usspg31.tourney.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import usspg31.tourney.model.PossibleScoring.ScoringType;
/**
 * Represents a tournament that can be carried out in an event
 */
public class Tournament implements Cloneable {
    public enum ExecutionState {
        NOT_EXECUTED,
        CURRENTLY_EXECUTED,
        FINISHED
    }
    private static final Logger log = Logger.getLogger(Tournament.class
            .getName());
    private final ObservableList<Player> registeredPlayers;
    private final ObservableList<Player> attendingPlayers;
    private final ObservableList<Player> remainingPlayers;
    private final ObservableList<Player> disqualifiedPlayers;
    // currently not considered when choosing the player who received a bye
    private final ObservableList<Player> receivedByePlayers;
    private final ObservableList<TournamentRound> rounds;
    private final StringProperty name;
    private final ObservableList<PlayerScore> scoreTable;
    private final ObservableList<TournamentAdministrator> administrators;
    private final StringProperty id;
    private final ObjectProperty<TournamentModule> ruleSet;
    private final ObjectProperty<ExecutionState> executionState;
    /**
     * Create a new tournament and initialize all its properties
     */
    public Tournament() {
        this.registeredPlayers = FXCollections.observableArrayList();
        this.attendingPlayers = FXCollections.observableArrayList();
        this.remainingPlayers = FXCollections.observableArrayList();
        this.disqualifiedPlayers = FXCollections.observableArrayList();
        this.receivedByePlayers = FXCollections.observableArrayList();
        this.rounds = FXCollections.observableArrayList();
        this.name = new SimpleStringProperty("");
        this.scoreTable = FXCollections.observableArrayList();
        this.administrators = FXCollections.observableArrayList();
        this.id = new SimpleStringProperty("");
        this.ruleSet = new SimpleObjectProperty<TournamentModule>(
                new TournamentModule());
        this.executionState = new SimpleObjectProperty<Tournament.ExecutionState>();
        this.setExecutionState(ExecutionState.NOT_EXECUTED);
    }
    /**
     * Get a list of all registered players in this tournament
     *
     * @return List of all registered players in this tournament
     */
    public ObservableList<Player> getRegisteredPlayers() {
        return this.registeredPlayers;
    }
    /**
     * Get a list of all attending players in this tournament
     *
     * @return List of all attending players in this tournament
     */
    public ObservableList<Player> getAttendingPlayers() {
        return this.attendingPlayers;
    }
    /**
     * Get a list of all players that have not been knocked out of this
     * tournament yet
     *
     * @return List of all remaining players in this tournament
     */
    public ObservableList<Player> getRemainingPlayers() {
        return this.remainingPlayers;
    }
    /**
     * Get a list of all tournament rounds in this tournament
     *
     * @return List of all tournament rounds in this tournament
     */
    public ObservableList<TournamentRound> getRounds() {
        return this.rounds;
    }
    /**
     * Get the list of all player which received a bye in the tournament
     *
     * @return List of all player who received a bye
     */
    public ObservableList<Player> getReceivedByePlayers() {
        return this.receivedByePlayers;
    }
    /**
     * Get the list of all player which were disqualified in the tournament
     *
     * @return List of all player who where disqualified
     */
    public ObservableList<Player> getDisqualifiedPlayers() {
        return this.disqualifiedPlayers;
    }
    /**
     * Get the name of this tournament
     *
     * @return Current name of this tournament
     */
    public String getName() {
        return this.name.get();
    }
    /**
     * Set the name of this tournament
     *
     * @param value
     *            New name of this tournament
     */
    public void setName(String value) {
        this.name.set(value);
    }
    /**
     * Get the name property of this tournament
     *
     * @return Name property of this tournament
     */
    public StringProperty nameProperty() {
        return this.name;
    }
    /**
     * Get the execution state of this tournament
     *
     * @return Current execution state of this tournament
     */
    public ExecutionState getExecutionState() {
        return this.executionState.get();
    }
    /**
     * Set the execution state of this tournament
     *
     * @param executionState
     *            New execution state of this tournament
     */
    public void setExecutionState(ExecutionState executionState) {
        this.executionState.set(executionState);
    }
    /**
     * Get the execution state property of this tournament
     *
     * @return execution state property of this tournament
     */
    public ObjectProperty<ExecutionState> executionStateProperty() {
        return this.executionState;
    }
    /**
     * Get all player scores in this tournament
     *
     * @return A list of all player scores in this tournament
     */
    public ObservableList<PlayerScore> getScoreTable() {
        return this.scoreTable;
    }
    /**
     * Get all tournament administrators in this event
     *
     * @return A list of all tournament administrators in this event
     */
    public ObservableList<TournamentAdministrator> getAdministrators() {
        return this.administrators;
    }
    /**
     * Get the ID of this event
     *
     * @return Current ID of this event
     */
    public String getId() {
        return this.id.get();
    }
    /**
     * Set the ID of this event
     *
     * @param id
     *            New ID of this event
     */
    public void setId(String id) {
        this.id.set(id);
    }
    /**
     * Get the tournament module that describes the rules of this tournament
     *
     * @return The current rule set of this tournament
     */
    public TournamentModule getRuleSet() {
        return this.ruleSet.get();
    }
    /**
     * Set the tournament module that describes the rules of this tournament
     *
     * @param value
     *            The new rule set of this tournament
     */
    public void setRuleSet(TournamentModule value) {
        this.ruleSet.set(value);
    }
    /**
     * Get the rule set property of this event
     *
     * @return Rule set property of this event
     */
    public ObjectProperty<TournamentModule> ruleSetProperty() {
        return this.ruleSet;
    }
    @Override
    public Object clone() {
        Tournament clone = new Tournament();
        clone.setName(this.getName());
        clone.setId(this.getId());
        clone.setRuleSet(this.getRuleSet());
        for (Player player : this.getRegisteredPlayers()) {
            clone.getRegisteredPlayers().add((Player) player.clone());
        }
        for (Player player : this.getAttendingPlayers()) {
            clone.getAttendingPlayers().add((Player) player.clone());
        }
        for (Player player : this.getDisqualifiedPlayers()) {
            clone.getDisqualifiedPlayers().add((Player) player.clone());
        }
        for (TournamentRound round : this.getRounds()) {
            clone.getRounds().add((TournamentRound) round.clone());
        }
        for (PlayerScore score : this.getScoreTable()) {
            clone.getScoreTable().add((PlayerScore) score.clone());
        }
        for (TournamentAdministrator admininstrator : this.getAdministrators()) {
            clone.getAdministrators().add(
                    (TournamentAdministrator) admininstrator.clone());
        }
        return clone;
    }
    /**
     * adds a score to the tournament score table
     *
     * @param score
     *            consist of the player and the score which gets added to the
     *            score table for the earlier mentioned player
     */
    public void addAScore(PlayerScore score) {
        if (this.rounds.size() != 1) {
            for (PlayerScore eachPlayerScore : this.scoreTable) {
                if (eachPlayerScore.getPlayer().getId()
                        .equals(score.getPlayer().getId())) {
                    for (int i = 0; i < eachPlayerScore.getScore().size(); i++) {
                        log.finer("The score "
                                + score.getScore().get(i)
                                + " was added to the score table in the tournament");
                        eachPlayerScore.getScore().set(
                                i,
                                eachPlayerScore.getScore().get(i)
                                        + score.getScore().get(i));
                    }
                }
            }
        } else {
            log.info("Added score after first round");
            this.scoreTable.add((PlayerScore) score.clone());
        }
    }
    /**
     * removes a score from the tournament score table
     *
     * @param score
     *            consist of the player and the score which gets added to the
     *            score table for the earlier mentioned player
     */
    public void removeAScore(PlayerScore score) {
        if (this.rounds.size() > 1) {
            for (PlayerScore eachPlayerScore : this.scoreTable) {
                if (eachPlayerScore.getPlayer().getId()
                        .equals(score.getPlayer().getId())) {
                    for (int i = 0; i < eachPlayerScore.getScore().size(); i++) {
                        log.finer("The score "
                                + score.getScore().get(i)
                                + " was removed from the score table in the tournament");
                        eachPlayerScore.getScore().set(
                                i,
                                eachPlayerScore.getScore().get(i)
                                        - score.getScore().get(i));
                    }
                }
            }
        }
    }
    /**
     * calculates the table strength for each player
     *
     */
    public void calculateTableStrength() {
        for (PossibleScoring possibleScore : this.getRuleSet()
                .getPossibleScores()) {
            if (possibleScore.getScoreType() == ScoringType.TABLE_STRENGTH) {
                for (Player player : this.attendingPlayers) {
                    this.calculateSinglePlayerTableStrength(player);
                }
            }
        }
    }
    public int calculateBestTableStrength(Player player) {
        ArrayList<PlayerScore> clonePlayerScore = new ArrayList<>();
        clonePlayerScore.addAll(this.scoreTable);
        Collections.sort(clonePlayerScore);
        int strength = 0;
        int count = 0;
        int i = 0;
        while (count < this.getRounds().size()) {
            if (!player.getId().equals(
                    clonePlayerScore.get(clonePlayerScore.size() - i - 1)
                            .getPlayer().getId())) {
                strength += clonePlayerScore
                        .get(clonePlayerScore.size() - 1 - i).getScore().get(0);
                count++;
            }
            i++;
            if (i == this.rounds.size() - 1) {
                break;
            }
        }
        return strength;
    }
    private void calculateSinglePlayerTableStrength(Player player) {
        Map<String, Player> opponentPlayers = new HashMap<String, Player>();
        ArrayList<Player> tmpPlayerStorage = new ArrayList<>();
        PlayerScore tableStrengthScore = new PlayerScore();
        int strength = 0;
        for (TournamentRound tRound : this.getRounds()) {
            for (Pairing tPairing : tRound.getPairings()) {
                for (Player opponent : tPairing.getOpponents()) {
                    if (opponent.getId().equals(player.getId())) {
                        tmpPlayerStorage = new ArrayList<>();
                        tmpPlayerStorage.addAll(tPairing.getOpponents());
                        for (int i = 0; i < tmpPlayerStorage.size(); i++) {
                            if (tmpPlayerStorage.get(i).getId()
                                    .equals(player.getId())) {
                                tmpPlayerStorage.remove(i);
                                break;
                            }
                        }
                        log.info("opponents size: " + opponentPlayers.size());
                        log.info("tmp size: " + tmpPlayerStorage.size());
                        for (int i = 0; i < tmpPlayerStorage.size(); i++) {
                            opponentPlayers.put(
                                    tmpPlayerStorage.get(i).getId(),
                                    tmpPlayerStorage.get(i));
                        }
                        break;
                    }
                }
            }
        }
        for (Entry<String, Player> opponent : opponentPlayers.entrySet()) {


Please complete the code given below. 
import os
import random
import re
import socket
import subprocess
import time
import zipfile
import tempfile
import base64
import shutil
import sys
from io import BytesIO
import pytest
from contextlib import contextmanager
from multiprocessing import Process
from urllib.request import urlopen, Request
from werkzeug.datastructures import Headers
from werkzeug.exceptions import RequestedRangeNotSatisfiable
from onionshare_cli.common import Common
from onionshare_cli.web import Web
from onionshare_cli.web.share_mode import parse_range_header
from onionshare_cli.settings import Settings
from onionshare_cli.mode_settings import ModeSettings
import onionshare_cli.web.receive_mode
# Stub requests.post, for receive mode webhook tests
webhook_url = None
webhook_data = None
def requests_post_stub(url, data, timeout, proxies):
    global webhook_url, webhook_data
    webhook_url = url
    webhook_data = data
onionshare_cli.web.receive_mode.requests.post = requests_post_stub
DEFAULT_ZW_FILENAME_REGEX = re.compile(r"^onionshare_[a-z2-7]{6}.zip$")
RANDOM_STR_REGEX = re.compile(r"^[a-z2-7]+$")
def web_obj(temp_dir, common_obj, mode, num_files=0):
    """Creates a Web object, in either share mode or receive mode, ready for testing"""
    common_obj.settings = Settings(common_obj)
    mode_settings = ModeSettings(common_obj)
    web = Web(common_obj, False, mode_settings, mode)
    web.generate_password()
    web.running = True
    web.cleanup_filenames == []
    web.app.testing = True
    # Share mode
    if mode == "share":
        # Add files
        files = []
        for _ in range(num_files):
            with tempfile.NamedTemporaryFile(delete=False, dir=temp_dir) as tmp_file:
                tmp_file.write(b"*" * 1024)
                files.append(tmp_file.name)
        web.share_mode.set_file_info(files)
    # Receive mode
    else:
        pass
    return web
class TestWeb:
    def test_share_mode(self, temp_dir, common_obj):
        web = web_obj(temp_dir, common_obj, "share", 3)
        assert web.mode == "share"
        with web.app.test_client() as c:
            # Load / without auth
            res = c.get("/")
            res.get_data()
            assert res.status_code == 401
            # Load / with invalid auth
            res = c.get("/", headers=self._make_auth_headers("invalid"))
            res.get_data()
            assert res.status_code == 401
            # Load / with valid auth
            res = c.get("/", headers=self._make_auth_headers(web.password))
            res.get_data()
            assert res.status_code == 200
            # Download
            res = c.get("/download", headers=self._make_auth_headers(web.password))
            res.get_data()
            assert res.status_code == 200
            assert (
                res.mimetype == "application/zip"
                or res.mimetype == "application/x-zip-compressed"
            )
    def test_share_mode_autostop_sharing_on(self, temp_dir, common_obj, temp_file_1024):
        web = web_obj(temp_dir, common_obj, "share", 3)
        web.settings.set("share", "autostop_sharing", True)
        assert web.running is True
        with web.app.test_client() as c:
            # Download the first time
            res = c.get("/download", headers=self._make_auth_headers(web.password))
            res.get_data()
            assert res.status_code == 200
            assert (
                res.mimetype == "application/zip"
                or res.mimetype == "application/x-zip-compressed"
            )
            assert web.running is False
    def test_share_mode_autostop_sharing_off(
        self, temp_dir, common_obj, temp_file_1024
    ):
        web = web_obj(temp_dir, common_obj, "share", 3)
        web.settings.set("share", "autostop_sharing", False)
        assert web.running is True
        with web.app.test_client() as c:
            # Download the first time
            res = c.get("/download", headers=self._make_auth_headers(web.password))
            res.get_data()
            assert res.status_code == 200
            assert (
                res.mimetype == "application/zip"
                or res.mimetype == "application/x-zip-compressed"
            )
            assert web.running is True
    def test_receive_mode(self, temp_dir, common_obj):
        web = web_obj(temp_dir, common_obj, "receive")
        assert web.mode == "receive"
        with web.app.test_client() as c:
            # Load / without auth
            res = c.get("/")
            res.get_data()
            assert res.status_code == 401
            # Load / with invalid auth
            res = c.get("/", headers=self._make_auth_headers("invalid"))
            res.get_data()
            assert res.status_code == 401
            # Load / with valid auth
            res = c.get("/", headers=self._make_auth_headers(web.password))
            res.get_data()
            assert res.status_code == 200
    def test_receive_mode_webhook(self, temp_dir, common_obj):
        global webhook_url, webhook_data
        webhook_url = None
        webhook_data = None
        web = web_obj(temp_dir, common_obj, "receive")
        assert web.mode == "receive"
        web.settings.set("receive", "webhook_url", "http://127.0.0.1:1337/example")
        web.proxies = None
        assert (
            web.settings.get("receive", "webhook_url")
            == "http://127.0.0.1:1337/example"
        )
        with web.app.test_client() as c:
            res = c.get("/", headers=self._make_auth_headers(web.password))
            res.get_data()
            assert res.status_code == 200
            res = c.post(
                "/upload-ajax",
                buffered=True,
                content_type="multipart/form-data",
                data={"file[]": (BytesIO(b"THIS IS A TEST FILE"), "new_york.jpg")},
                headers=self._make_auth_headers(web.password),
            )
            res.get_data()
            assert res.status_code == 200
            assert webhook_url == "http://127.0.0.1:1337/example"
            assert webhook_data == "1 file submitted to OnionShare"
    def test_receive_mode_message_no_files(self, temp_dir, common_obj):
        web = web_obj(temp_dir, common_obj, "receive")
        data_dir = os.path.join(temp_dir, "OnionShare")
        os.makedirs(data_dir, exist_ok=True)
        web.settings.set("receive", "data_dir", data_dir)
        with web.app.test_client() as c:
            res = c.post(
                "/upload-ajax",
                buffered=True,
                content_type="multipart/form-data",
                data={"text": "you know just sending an anonymous message"},
                headers=self._make_auth_headers(web.password),
            )
            content = res.get_data()
            assert res.status_code == 200
            assert b"Message submitted" in content
        # ~/OnionShare should have a folder for the date
        filenames = os.listdir(data_dir)
        assert len(filenames) == 1
        data_dir_date = os.path.join(data_dir, filenames[0])
        # The date folder should have a single message txt file, no folders
        filenames = os.listdir(data_dir_date)
        assert len(filenames) == 1
        assert filenames[0].endswith("-message.txt")
        shutil.rmtree(data_dir)
    def test_receive_mode_message_and_files(self, temp_dir, common_obj):
        web = web_obj(temp_dir, common_obj, "receive")
        data_dir = os.path.join(temp_dir, "OnionShare")
        os.makedirs(data_dir, exist_ok=True)
        web.settings.set("receive", "data_dir", data_dir)
        with web.app.test_client() as c:
            res = c.post(
                "/upload-ajax",
                buffered=True,
                content_type="multipart/form-data",
                data={
                    "file[]": (BytesIO(b"THIS IS A TEST FILE"), "new_york.jpg"),
                    "text": "you know just sending an anonymous message",
                },
                headers=self._make_auth_headers(web.password),
            )
            content = res.get_data()
            assert res.status_code == 200
            assert b"Message submitted, uploaded new_york.jpg" in content
        # Date folder should have a time folder with new_york.jpg, and a text message file
        data_dir_date = os.path.join(data_dir, os.listdir(data_dir)[0])
        filenames = os.listdir(data_dir_date)
        assert len(filenames) == 2
        time_str = filenames[0][0:6]
        assert time_str in filenames
        assert f"{time_str}-message.txt" in filenames
        data_dir_time = os.path.join(data_dir_date, time_str)
        assert os.path.isdir(data_dir_time)
        assert os.path.exists(os.path.join(data_dir_time, "new_york.jpg"))
        shutil.rmtree(data_dir)
    def test_receive_mode_files_no_message(self, temp_dir, common_obj):
        web = web_obj(temp_dir, common_obj, "receive")
        data_dir = os.path.join(temp_dir, "OnionShare")
        os.makedirs(data_dir, exist_ok=True)
        web.settings.set("receive", "data_dir", data_dir)
        with web.app.test_client() as c:
            res = c.post(
                "/upload-ajax",
                buffered=True,
                content_type="multipart/form-data",
                data={"file[]": (BytesIO(b"THIS IS A TEST FILE"), "new_york.jpg")},
                headers=self._make_auth_headers(web.password),
            )
            content = res.get_data()
            assert res.status_code == 200
            assert b"Uploaded new_york.jpg" in content
        # Date folder should have just a time folder with new_york.jpg
        data_dir_date = os.path.join(data_dir, os.listdir(data_dir)[0])
        filenames = os.listdir(data_dir_date)
        assert len(filenames) == 1
        time_str = filenames[0][0:6]
        assert time_str in filenames
        assert f"{time_str}-message.txt" not in filenames
        data_dir_time = os.path.join(data_dir_date, time_str)
        assert os.path.isdir(data_dir_time)
        assert os.path.exists(os.path.join(data_dir_time, "new_york.jpg"))
        shutil.rmtree(data_dir)
    def test_receive_mode_no_message_no_files(self, temp_dir, common_obj):
        web = web_obj(temp_dir, common_obj, "receive")
        data_dir = os.path.join(temp_dir, "OnionShare")
        os.makedirs(data_dir, exist_ok=True)
        web.settings.set("receive", "data_dir", data_dir)
        with web.app.test_client() as c:
            res = c.post(
                "/upload-ajax",
                buffered=True,
                content_type="multipart/form-data",
                data={},
                headers=self._make_auth_headers(web.password),
            )
            content = res.get_data()
            assert res.status_code == 200
            assert b"Nothing submitted" in content
        # Date folder should be empty
        data_dir_date = os.path.join(data_dir, os.listdir(data_dir)[0])
        filenames = os.listdir(data_dir_date)
        assert len(filenames) == 0
        shutil.rmtree(data_dir)
    def test_public_mode_on(self, temp_dir, common_obj):
        web = web_obj(temp_dir, common_obj, "receive")
        web.settings.set("general", "public", True)
        with web.app.test_client() as c:
            # Loading / should work without auth
            res = c.get("/")
            res.get_data()
            assert res.status_code == 200
    def test_public_mode_off(self, temp_dir, common_obj):
        web = web_obj(temp_dir, common_obj, "receive")
        web.settings.set("general", "public", False)
        with web.app.test_client() as c:
            # Load / without auth


Please complete the code given below. 
package info.nightscout.androidaps.plugins.general.nsclient;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.text.Spanned;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventChargingState;
import info.nightscout.androidaps.events.EventNetworkChange;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientResend;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.HtmlHelper;
import info.nightscout.androidaps.utils.ToastUtils;
import info.nightscout.androidaps.utils.buildHelper.BuildHelper;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
@Singleton
public class NSClientPlugin extends PluginBase {
    private final CompositeDisposable disposable = new CompositeDisposable();
    private final AAPSLogger aapsLogger;
    private final RxBusWrapper rxBus;
    private final ResourceHelper resourceHelper;
    private final Context context;
    private final FabricPrivacy fabricPrivacy;
    private final SP sp;
    private final Config config;
    private final BuildHelper buildHelper;
    public Handler handler;
    private final List<EventNSClientNewLog> listLog = new ArrayList<>();
    Spanned textLog = HtmlHelper.INSTANCE.fromHtml("");
    public boolean paused;
    boolean autoscroll;
    public String status = "";
    public NSClientService nsClientService = null;
    private final NsClientReceiverDelegate nsClientReceiverDelegate;
    @Inject
    public NSClientPlugin(
            HasAndroidInjector injector,
            AAPSLogger aapsLogger,
            RxBusWrapper rxBus,
            ResourceHelper resourceHelper,
            Context context,
            FabricPrivacy fabricPrivacy,
            SP sp,
            NsClientReceiverDelegate nsClientReceiverDelegate,
            Config config,
            BuildHelper buildHelper
    ) {
        super(new PluginDescription()
                        .mainType(PluginType.GENERAL)
                        .fragmentClass(NSClientFragment.class.getName())
                        .pluginIcon(R.drawable.ic_nightscout_syncs)
                        .pluginName(R.string.nsclientinternal)
                        .shortName(R.string.nsclientinternal_shortname)
                        .preferencesId(R.xml.pref_nsclientinternal)
                        .description(R.string.description_ns_client),
                aapsLogger, resourceHelper, injector
        );
        this.aapsLogger = aapsLogger;
        this.rxBus = rxBus;
        this.resourceHelper = resourceHelper;
        this.context = context;
        this.fabricPrivacy = fabricPrivacy;
        this.sp = sp;
        this.nsClientReceiverDelegate = nsClientReceiverDelegate;
        this.config = config;
        this.buildHelper = buildHelper;
        if (config.getNSCLIENT()) {
            getPluginDescription().alwaysEnabled(true).visibleByDefault(true);
        }
        if (handler == null) {
            HandlerThread handlerThread = new HandlerThread(NSClientPlugin.class.getSimpleName() + "Handler");
            handlerThread.start();
            handler = new Handler(handlerThread.getLooper());
        }
    }
    public boolean isAllowed() {
        return nsClientReceiverDelegate.allowed;
    }
    @Override
    protected void onStart() {
        paused = sp.getBoolean(R.string.key_nsclientinternal_paused, false);
        autoscroll = sp.getBoolean(R.string.key_nsclientinternal_autoscroll, true);
        Intent intent = new Intent(context, NSClientService.class);
        context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        super.onStart();
        nsClientReceiverDelegate.grabReceiversState();
        disposable.add(rxBus
                .toObservable(EventNSClientStatus.class)
                .observeOn(Schedulers.io())
                .subscribe(event -> {
                    status = event.getStatus(resourceHelper);
                    rxBus.send(new EventNSClientUpdateGUI());
                }, fabricPrivacy::logException)
        );
        disposable.add(rxBus
                .toObservable(EventNetworkChange.class)
                .observeOn(Schedulers.io())
                .subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), fabricPrivacy::logException)
        );
        disposable.add(rxBus
                .toObservable(EventPreferenceChange.class)
                .observeOn(Schedulers.io())
                .subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), fabricPrivacy::logException)
        );
        disposable.add(rxBus
                .toObservable(EventAppExit.class)
                .observeOn(Schedulers.io())
                .subscribe(event -> {
                    if (nsClientService != null) {
                        context.unbindService(mConnection);
                    }
                }, fabricPrivacy::logException)
        );
        disposable.add(rxBus
                .toObservable(EventNSClientNewLog.class)
                .observeOn(Schedulers.io())
                .subscribe(event -> {
                    addToLog(event);
                    aapsLogger.debug(LTag.NSCLIENT, event.getAction() + " " + event.getLogText());
                }, fabricPrivacy::logException)
        );
        disposable.add(rxBus
                .toObservable(EventChargingState.class)
                .observeOn(Schedulers.io())
                .subscribe(event -> nsClientReceiverDelegate.onStatusEvent(event), fabricPrivacy::logException)
        );
        disposable.add(rxBus
                .toObservable(EventNSClientResend.class)
                .observeOn(Schedulers.io())
                .subscribe(event -> resend(event.getReason()), fabricPrivacy::logException)
        );
    }
    @Override
    protected void onStop() {
        context.getApplicationContext().unbindService(mConnection);
        disposable.clear();
        super.onStop();
    }
    @Override
    public void preprocessPreferences(@NotNull PreferenceFragmentCompat preferenceFragment) {
        super.preprocessPreferences(preferenceFragment);
        if (config.getNSCLIENT()) {
            SwitchPreference key_ns_uploadlocalprofile = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_uploadlocalprofile));
            if (key_ns_uploadlocalprofile != null) key_ns_uploadlocalprofile.setVisible(false);
            SwitchPreference key_ns_autobackfill = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_autobackfill));
            if (key_ns_autobackfill != null) key_ns_autobackfill.setVisible(false);
            SwitchPreference key_ns_create_announcements_from_errors = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_create_announcements_from_errors));
            if (key_ns_create_announcements_from_errors != null)
                key_ns_create_announcements_from_errors.setVisible(false);
            SwitchPreference key_ns_create_announcements_from_carbs_req = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_create_announcements_from_carbs_req));
            if (key_ns_create_announcements_from_carbs_req != null)
                key_ns_create_announcements_from_carbs_req.setVisible(false);
            SwitchPreference key_ns_upload_only = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_upload_only));
            if (key_ns_upload_only != null) {
                key_ns_upload_only.setVisible(false);
                key_ns_upload_only.setEnabled(false);
            }
            SwitchPreference key_ns_sync_use_absolute = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_sync_use_absolute));
            if (key_ns_sync_use_absolute != null) key_ns_sync_use_absolute.setVisible(false);
        } else {
            // APS or pumpcontrol mode
            SwitchPreference key_ns_upload_only = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_upload_only));
            if (key_ns_upload_only != null)
                key_ns_upload_only.setVisible(buildHelper.isEngineeringMode());
        }
    }
    private final ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceDisconnected(ComponentName name) {
            aapsLogger.debug(LTag.NSCLIENT, "Service is disconnected");
            nsClientService = null;
        }
        public void onServiceConnected(ComponentName name, IBinder service) {
            aapsLogger.debug(LTag.NSCLIENT, "Service is connected");
            NSClientService.LocalBinder mLocalBinder = (NSClientService.LocalBinder) service;
            if (mLocalBinder != null) // is null when running in roboelectric


Please complete the code given below. 
from __future__ import with_statement, print_function
# Script for building the _ssl and _hashlib modules for Windows.
# Uses Perl to setup the OpenSSL environment correctly
# and build OpenSSL, then invokes a simple nmake session
# for the actual _ssl.pyd and _hashlib.pyd DLLs.
# THEORETICALLY, you can:
# * Unpack the latest SSL release one level above your main Python source
#   directory.  It is likely you will already find the zlib library and
#   any other external packages there.
# * Install ActivePerl and ensure it is somewhere on your path.
# * Run this script from the PCBuild directory.
#
# it should configure and build SSL, then build the _ssl and _hashlib
# Python extensions without intervention.
# Modified by Christian Heimes
# Now this script supports pre-generated makefiles and assembly files.
# Developers don't need an installation of Perl anymore to build Python. A svn
# checkout from our svn repository is enough.
#
# In Order to create the files in the case of an update you still need Perl.
# Run build_ssl in this order:
# python.exe build_ssl.py Release x64
# python.exe build_ssl.py Release Win32
import os, sys, re, shutil
# Find all "foo.exe" files on the PATH.
def find_all_on_path(filename, extras = None):
    entries = os.environ["PATH"].split(os.pathsep)
    ret = []
    for p in entries:
        fname = os.path.abspath(os.path.join(p, filename))
        if os.path.isfile(fname) and fname not in ret:
            ret.append(fname)
    if extras:
        for p in extras:
            fname = os.path.abspath(os.path.join(p, filename))
            if os.path.isfile(fname) and fname not in ret:
                ret.append(fname)
    return ret
# Find a suitable Perl installation for OpenSSL.
# cygwin perl does *not* work.  ActivePerl does.
# Being a Perl dummy, the simplest way I can check is if the "Win32" package
# is available.
def find_working_perl(perls):
    for perl in perls:
        fh = os.popen('"%s" -e "use Win32;"' % perl)
        fh.read()
        rc = fh.close()
        if rc:
            continue
        return perl
    print("Can not find a suitable PERL:")
    if perls:
        print(" the following perl interpreters were found:")
        for p in perls:
            print(" ", p)
        print(" None of these versions appear suitable for building OpenSSL")
    else:
        print(" NO perl interpreters were found on this machine at all!")
    print(" Please install ActivePerl and ensure it appears on your path")
    return None
# Locate the best SSL directory given a few roots to look into.
def find_best_ssl_dir(sources):
    candidates = []
    for s in sources:
        try:
            # note: do not abspath s; the build will fail if any
            # higher up directory name has spaces in it.
            fnames = os.listdir(s)
        except os.error:
            fnames = []
        for fname in fnames:
            fqn = os.path.join(s, fname)
            if os.path.isdir(fqn) and fname.startswith("openssl-"):
                candidates.append(fqn)
    # Now we have all the candidates, locate the best.
    best_parts = []
    best_name = None
    for c in candidates:
        parts = re.split("[.-]", os.path.basename(c))[1:]
        # eg - openssl-0.9.7-beta1 - ignore all "beta" or any other qualifiers
        if len(parts) >= 4:
            continue
        if parts > best_parts:
            best_parts = parts
            best_name = c
    if best_name is not None:
        print("Found an SSL directory at '%s'" % (best_name,))
    else:
        print("Could not find an SSL directory in '%s'" % (sources,))
    sys.stdout.flush()
    return best_name
def create_makefile64(makefile, m32):
    """Create and fix makefile for 64bit
    Replace 32 with 64bit directories
    """
    if not os.path.isfile(m32):
        return
    with open(m32) as fin:
        with open(makefile, 'w') as fout:
            for line in fin:
                line = line.replace("=tmp32", "=tmp64")
                line = line.replace("=out32", "=out64")
                line = line.replace("=inc32", "=inc64")
                # force 64 bit machine
                line = line.replace("MKLIB=lib", "MKLIB=lib /MACHINE:X64")
                line = line.replace("LFLAGS=", "LFLAGS=/MACHINE:X64 ")
                # don't link against the lib on 64bit systems
                line = line.replace("bufferoverflowu.lib", "")
                fout.write(line)
    os.unlink(m32)
def fix_makefile(makefile):
    """Fix some stuff in all makefiles
    """
    if not os.path.isfile(makefile):
        return
    # 2.4 compatibility
    fin = open(makefile)
    if 1: # with open(makefile) as fin:
        lines = fin.readlines()
        fin.close()
    fout = open(makefile, 'w')
    if 1: # with open(makefile, 'w') as fout:
        for line in lines:
            if line.startswith("PERL="):
                continue
            if line.startswith("CP="):
                line = "CP=copy\n"
            if line.startswith("MKDIR="):
                line = "MKDIR=mkdir\n"
            if line.startswith("CFLAG="):
                line = line.strip()
                for algo in ("RC5", "MDC2", "IDEA"):
                    noalgo = " -DOPENSSL_NO_%s" % algo
                    if noalgo not in line:
                        line = line + noalgo
                line = line + '\n'
            fout.write(line)
    fout.close()
def run_configure(configure, do_script):
    print("perl Configure "+configure)
    os.system("perl Configure "+configure)
    print(do_script)
    os.system(do_script)
def main():
    build_all = "-a" in sys.argv
    if sys.argv[1] == "Release":
        debug = False
    elif sys.argv[1] == "Debug":
        debug = True
    else:
        raise ValueError(str(sys.argv))
    if sys.argv[2] == "Win32":
        arch = "x86"
        configure = "VC-WIN32"
        do_script = "ms\\do_nasm"
        makefile="ms\\nt.mak"
        m32 = makefile
    elif sys.argv[2] == "x64":
        arch="amd64"
        configure = "VC-WIN64A"
        do_script = "ms\\do_win64a"
        makefile = "ms\\nt64.mak"
        m32 = makefile.replace('64', '')
        #os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON"
    else:
        raise ValueError(str(sys.argv))
    make_flags = ""
    if build_all:
        make_flags = "-a"
    # perl should be on the path, but we also look in "\perl" and "c:\\perl"
    # as "well known" locations
    perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
    perl = find_working_perl(perls)
    if perl:
        print("Found a working perl at '%s'" % (perl,))
    else:
        print("No Perl installation was found. Existing Makefiles are used.")
    sys.stdout.flush()
    # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
    ssl_dir = find_best_ssl_dir(("..\\..",))
    if ssl_dir is None:
        sys.exit(1)
    old_cd = os.getcwd()
    try:
        os.chdir(ssl_dir)
        # rebuild makefile when we do the role over from 32 to 64 build
        if arch == "amd64" and os.path.isfile(m32) and not os.path.isfile(makefile):
            os.unlink(m32)
        # If the ssl makefiles do not exist, we invoke Perl to generate them.
        # Due to a bug in this script, the makefile sometimes ended up empty
        # Force a regeneration if it is.
        if not os.path.isfile(makefile) or os.path.getsize(makefile)==0:
            if perl is None:
                print("Perl is required to build the makefiles!")
                sys.exit(1)
            print("Creating the makefiles...")
            sys.stdout.flush()
            # Put our working Perl at the front of our path
            os.environ["PATH"] = os.path.dirname(perl) + \
                                          os.pathsep + \
                                          os.environ["PATH"]
            run_configure(configure, do_script)
            if debug:
                print("OpenSSL debug builds aren't supported.")
            #if arch=="x86" and debug:
            #    # the do_masm script in openssl doesn't generate a debug
            #    # build makefile so we generate it here:
            #    os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile)


Please complete the code given below. 
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
public class TowerEditor : EditorWindow {
    
	int levelCap=1;
	
	[SerializeField] static string[] nameList=new string[0];
	
	[SerializeField] static UnitTower[] towerList=new UnitTower[0];
	
	
	UnitTower newTower;
	
	UnitTower tower;
	
	int index=0;
	int towerType=0;
	int towerTargetMode=0;
	//~ int towerTargetPriority=0;
	//~ int towerTargetArea=0;
	//~ int turretAnimateMode=0;
	//~ int turretRotationMode=0;
	
	static string[] towerTypeLabel=new string[3];
	static string[] towerTargetModeLabel=new string[3];
	static string[] towerTargetPriorityLabel=new string[4];
	static string[] towerTargetAreaLabel=new string[3];
	static string[] turretAnimateModeLabel=new string[3];
	static string[] turretRotationModeLabel=new string[2];
    
	private bool[] indicatorFlags=new bool[1];
	
	private bool showAnimationList=false;
	private string showAnimationText="Show animation configuration";
	
	private bool showSoundList=false;
	private string showSoundText="Show sfx list";
	
	static private TowerEditor window;
	
    // Add menu named "TowerEditor" to the Window menu
    //[MenuItem ("TDTK/TowerEditor")]
    public static void Init () {
        // Get existing open window or if none, make a new one:
        window = (TowerEditor)EditorWindow.GetWindow(typeof (TowerEditor));
		window.minSize=new Vector2(610, 650);
		
		window.indicatorFlags[0]=true;
		
		GetTower();
		
		towerTypeLabel[0]="Turret Tower";
		towerTypeLabel[1]="AOE Tower";
		towerTypeLabel[2]="Support Tower";
		
		towerTargetModeLabel[0]="Hybrid";
		towerTargetModeLabel[1]="Air";
		towerTargetModeLabel[2]="Ground";
		
		towerTargetPriorityLabel[0]="Nearest";
		towerTargetPriorityLabel[1]="Weakest";
		towerTargetPriorityLabel[2]="Toughest";
		towerTargetPriorityLabel[3]="Random";
		
		towerTargetAreaLabel[0]="AllAround";
		towerTargetAreaLabel[1]="DirectionalCone";
		towerTargetAreaLabel[2]="StraightLine";
		
		turretAnimateModeLabel[0]="Full";
		turretAnimateModeLabel[1]="Y-Axis Only";
		turretAnimateModeLabel[2]="None";
		
		turretRotationModeLabel[0]="FullTurret";
		turretRotationModeLabel[1]="SeparatedBarrel";
		
    }
    
	static BuildManager buildManager;
	
	static void GetTower(){
		towerList=new UnitTower[0];
		nameList=new string[0];
		
		buildManager=(BuildManager)FindObjectOfType(typeof(BuildManager));
		
		if(buildManager!=null){
			towerList=buildManager.towers;
			
			nameList=new string[towerList.Length];
			for(int i=0; i<towerList.Length; i++){
				nameList[i]=towerList[i].name;
			}
		}
		else{
			towerList=new UnitTower[0];
			nameList=new string[0];
		}
		
	}
	
	float startX, startY, height, spaceY, lW;
	int rscCount=1;
	
	private Vector2 scrollPos;
	
    void OnGUI () {
		scrollPos = GUI.BeginScrollView(new Rect(0, 0, window.position.width, window.position.height), scrollPos, new Rect(0, 0, Mathf.Max(window.position.width, 610+(levelCap-3)*180), 1270));
		
		GUI.changed = false;
		
		
		{
			startX=3;
			startY=3;
			height=18;
			spaceY=height+startX;
			
			lW=100;	//label width, the offset from label to the editable field
			
			if(towerList.Length>0) {
				index = EditorGUI.Popup(new Rect(startX, startY, 300, height), "Tower:", index, nameList);
				
				//new tower, update index
				levelCap=towerList[index].levelCap;			
				EditorGUI.LabelField(new Rect(320+startX, startY, 200, height), "LevelCap: "+towerList[index].levelCap.ToString());
				EditorGUI.LabelField(new Rect(395+startX, startY, 200, height), "Change to: ");
				levelCap = EditorGUI.IntField(new Rect(startX+465, startY, 20, height), levelCap);
				levelCap = Mathf.Max(1, levelCap);
				UpdateIndicatorFlags(levelCap);
				
				if(levelCap!=towerList[index].levelCap){
					towerList[index].levelCap=levelCap;
					towerList[index].UpdateTowerUpgradeStat(levelCap-1);
				}
				
				//assign appropriate towerType index
				if(towerList[index].type==_TowerType.TurretTower) towerType=0;
				else if(towerList[index].type==_TowerType.AOETower) towerType=1;
				//~ else if(towerList[index].type==_TowerType.DirectionalAOETower) towerType=2;
				else if(towerList[index].type==_TowerType.SupportTower) towerType=3;
				//~ else if(towerList[index].type==_TowerType.ResourceTower) towerType=4;
				//~ else if(towerList[index].type==_TowerType.Mine) towerType=5;
				//~ else if(towerList[index].type==_TowerType.Block) towerType=6;
				
				//assign appropriate towerTargetMode index
				if(towerList[index].targetMode==_TargetMode.Hybrid) towerTargetMode=0;
				else if(towerList[index].targetMode==_TargetMode.Air) towerTargetMode=1;
				else if(towerList[index].targetMode==_TargetMode.Ground) towerTargetMode=2;
				
				//~ if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.DirectionalAOETower){
					//~ if(towerList[index].animateTurret==_TurretAni.Full) turretAnimateMode=0;
					//~ if(towerList[index].animateTurret==_TurretAni.YAxis) turretAnimateMode=1;
					//~ if(towerList[index].animateTurret==_TurretAni.None) turretAnimateMode=2;
				//~ }
				
				//~ if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.DirectionalAOETower){
					//~ if(towerList[index].turretRotationModel==_RotationMode.FullTurret) turretRotationMode=0;
					//~ if(towerList[index].turretRotationModel==_RotationMode.SeparatedBarrel) turretRotationMode=1;
				//~ }
				
				//~ if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.DirectionalAOETower){
					//~ if(towerList[index].targetPriority==_TargetPriority.Nearest) towerTargetPriority=0;
					//~ if(towerList[index].targetPriority==_TargetPriority.Weakest) towerTargetPriority=1;
					//~ if(towerList[index].targetPriority==_TargetPriority.Toughest) towerTargetPriority=2;
					//~ if(towerList[index].targetPriority==_TargetPriority.Random) towerTargetPriority=3;
				//~ }
				
				//~ if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.DirectionalAOETower){
					//~ if(towerList[index].targetingArea==_TargetingArea.AllAround) towerTargetArea=0;
					//~ if(towerList[index].targetingArea==_TargetingArea.DirectionalCone) towerTargetArea=1;
					//~ if(towerList[index].targetingArea==_TargetingArea.StraightLine) towerTargetArea=2;
				//~ }
				
				if(GUI.Button(new Rect(Mathf.Max(startX+500, window.position.width-160), startY, 140, height), "Update Build Manager")){
					GetTower();
					GUI.EndScrollView();
					return;
				}
				
				towerList[index].unitName = EditorGUI.TextField(new Rect(startX, startY+=30, 300, height-3), "TowerName:", towerList[index].unitName);
				
				EditorGUI.LabelField(new Rect(startX+320, startY, 70, height), "Icon: ");
				towerList[index].icon=(Texture)EditorGUI.ObjectField(new Rect(startX+360, startY, 70, 70), towerList[index].icon, typeof(Texture), false);
						  
				towerType = EditorGUI.Popup(new Rect(startX, startY+=20, 300, 15), "TowerType:", towerType, towerTypeLabel);
				if(towerType==0) towerList[index].type=_TowerType.TurretTower;
				else if(towerType==1) towerList[index].type=_TowerType.AOETower;
				//~ else if(towerType==2) towerList[index].type=_TowerType.DirectionalAOETower;
				else if(towerType==3) towerList[index].type=_TowerType.SupportTower;
				//~ else if(towerType==4) towerList[index].type=_TowerType.ResourceTower;
				//~ else if(towerType==5) towerList[index].type=_TowerType.Mine;
				//~ else if(towerType==6) towerList[index].type=_TowerType.Block;
				
				if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.AOETower){//|| towerList[index].type==_TowerType.DirectionalAOETower
					towerTargetMode = EditorGUI.Popup(new Rect(startX, startY+=20, 300, 15), "TargetingMode:", towerTargetMode, towerTargetModeLabel);
					if(towerTargetMode==0) towerList[index].targetMode=_TargetMode.Hybrid;
					else if(towerTargetMode==1) towerList[index].targetMode=_TargetMode.Air;
					else if(towerTargetMode==2) towerList[index].targetMode=_TargetMode.Ground;
				}
				else startY+=20;
				//towerList[index].armorType=EditorGUI.IntField(new Rect(startX, startY+=20, 300, height-3), "ArmorType:", towerList[index].armorType);
				//if(towerList[index].type!=_TowerType.SupportTower && towerList[index].type!=_TowerType.ResourceTower && towerList[index].type!=_TowerType.Block){
				//	towerList[index].armorType=EditorGUI.IntField(new Rect(startX, startY+=20, 300, height-3), "DamageType:", towerList[index].damageType);
				//}
				//else startY+=20;
				
				//~ if(towerList[index].type==_TowerType.TurretTower){// || towerList[index].type==_TowerType.DirectionalAOETower){
					//~ towerTargetArea = EditorGUI.Popup(new Rect(startX, startY+=20, 300, 15), "TargetingArea:", towerTargetArea, towerTargetAreaLabel);
					//~ if(towerTargetArea==0) towerList[index].targetingArea=_TargetingArea.AllAround;
					//~ else if(towerTargetArea==1) towerList[index].targetingArea=_TargetingArea.DirectionalCone;
					//~ else if(towerTargetArea==2) towerList[index].targetingArea=_TargetingArea.StraightLine;
					
					//~ if(towerList[index].targetingArea!=_TargetingArea.AllAround){
						//~ towerList[index].matchTowerDir2TargetDir=EditorGUI.Toggle(new Rect(startX+205, startY+20-1, 300, height-3), towerList[index].matchTowerDir2TargetDir);
						//~ EditorGUI.LabelField(new Rect(startX+220, startY+20-1, 300, height-3), "FaceDirection");
						//~ towerList[index].targetingDirection = EditorGUI.FloatField(new Rect(startX, startY+=20, 195, height-3), "TargetingDirection:", towerList[index].targetingDirection);
					//~ }
					//~ else startY+=20;
				//~ }
				//~ else startY+=40;
				
				
				
				//~ if(towerList[index].targetingArea==_TargetingArea.DirectionalCone){
					//~ towerList[index].targetingFOV = EditorGUI.FloatField(new Rect(startX, startY+=20, 300, height-3), "TargetingFOV:", towerList[index].targetingFOV);
				//~ }
				//~ else startY+=20;
				
				//~ if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.DirectionalAOETower){
					//~ if(towerList[index].targetingArea!=_TargetingArea.StraightLine){
						//~ towerTargetPriority = EditorGUI.Popup(new Rect(startX, startY+=20, 300, 15), "TargetingPriority:", towerTargetPriority, towerTargetPriorityLabel);
						//~ if(towerTargetPriority==0) towerList[index].targetPriority=_TargetPriority.Nearest;
						//~ else if(towerTargetPriority==1) towerList[index].targetPriority=_TargetPriority.Weakest;
						//~ else if(towerTargetPriority==2) towerList[index].targetPriority=_TargetPriority.Toughest;
						//~ else if(towerTargetPriority==2) towerList[index].targetPriority=_TargetPriority.Random;
					//~ }
					//~ //else startY+=20;
				//~ }
				//~ else startY+=20;
				
				//~ if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.DirectionalAOETower){
					//~ turretAnimateMode = EditorGUI.Popup(new Rect(startX, startY+=20, 300, 15), "TurretAnimateMode:", turretAnimateMode, turretAnimateModeLabel);
					//~ if(turretAnimateMode==0) towerList[index].animateTurret=_TurretAni.Full;
					//~ else if(turretAnimateMode==1) towerList[index].animateTurret=_TurretAni.YAxis;
					//~ else if(turretAnimateMode==2) towerList[index].animateTurret=_TurretAni.None;
					
					//~ turretRotationMode = EditorGUI.Popup(new Rect(startX, startY+=20, 300, 15), "TurretRotationMode:", turretRotationMode, turretRotationModeLabel);
					//~ if(turretRotationMode==0) towerList[index].turretRotationModel=_RotationMode.FullTurret;
					//~ else if(turretRotationMode==1) towerList[index].turretRotationModel=_RotationMode.SeparatedBarrel;
				//~ }
				//~ else startY+=20;
				
				//~ if(towerList[index].type==_TowerType.DirectionalAOETower){
					//~ towerList[index].aoeConeAngle = EditorGUI.FloatField(new Rect(startX, startY+=20, 300, height-3), "AOE Cone Angle:", towerList[index].aoeConeAngle);
				//~ }
				
				
				//~ if(towerList[index].type==_TowerType.Mine){
					//~ towerList[index].mineOneOff=EditorGUI.Toggle(new Rect(startX, startY, 300, 15), "DestroyUponTriggered:", towerList[index].mineOneOff);
				//~ }
				
				startY+=5;
				towerList[index].buildingEffect=(GameObject)EditorGUI.ObjectField(new Rect(startX, startY+=20, 300, 15), "BuildingEffect: ", towerList[index].buildingEffect, typeof(GameObject), false);
				towerList[index].buildingDoneEffect=(GameObject)EditorGUI.ObjectField(new Rect(startX, startY+=20, 300, 15), "BuildingDoneEffect: ", towerList[index].buildingDoneEffect, typeof(GameObject), false);
				startY+=5;
				
				showAnimationList=EditorGUI.Foldout(new Rect(startX, startY+=spaceY, 300, 15), showAnimationList, showAnimationText);
				if(showAnimationList){
					showAnimationText="Hide build animation list";
					towerList[index].turretBuildAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - TurretAnimationComponent: ", towerList[index].turretBuildAnimationBody, typeof(Animation), false);
					towerList[index].turretBuildAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - TurretAnimation: ", towerList[index].turretBuildAnimation, typeof(AnimationClip), false);
					towerList[index].baseBuildAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - BaseAnimationComponent: ", towerList[index].baseBuildAnimationBody, typeof(Animation), false);
					towerList[index].baseBuildAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - BaseAnimation: ", towerList[index].baseBuildAnimation, typeof(AnimationClip), false);
					//~ towerList[index].fireAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - FireAnimationBody: ", towerList[index].fireAnimationBody, typeof(Animation), false);
					//~ towerList[index].fireAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - FireAnimation: ", towerList[index].fireAnimation, typeof(AnimationClip), false);
					//~ towerList[index].fireAnimationBaseBody=(Animation)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - FireAnimationBaseBody: ", towerList[index].fireAnimationBaseBody, typeof(Animation), false);
					//~ towerList[index].fireAnimationBase=(AnimationClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - FireAnimationBase: ", towerList[index].fireAnimationBase, typeof(AnimationClip), false);
				}
				else{
					showAnimationText="Show build animation list";
				}
				
				
				showSoundList=EditorGUI.Foldout(new Rect(startX, startY+=spaceY, 300, 15), showSoundList, showSoundText);
				if(showSoundList){
					towerList[index].shootSound=(AudioClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - ShootSound: ", towerList[index].shootSound, typeof(AudioClip), false);
					towerList[index].buildingSound=(AudioClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - BuildingSound: ", towerList[index].buildingSound, typeof(AudioClip), false);
					towerList[index].builtSound=(AudioClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - BuiltSound: ", towerList[index].builtSound, typeof(AudioClip), false);
					towerList[index].soldSound=(AudioClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - SoldSound: ", towerList[index].soldSound, typeof(AudioClip), false);
					
					showSoundText="Hide sfx list";
				}
				else{
					showSoundText="Show sfx list";
				}
				
				
				EditorGUI.LabelField(new Rect(startX, startY+=25, 150, height), "Tower Description: ");
				towerList[index].description=EditorGUI.TextArea(new Rect(startX, startY+=17, 485, 50), towerList[index].description);
				startY+=25;
				
				
				//position in which the stat editor for tower levels start
				startY+=20;
				float tabYPos=startY;
				
				
				rscCount=1;
				
				//TowerStat section
				//if(index>=0 && index<towerList.Length){
					
					indicatorFlags[0] = EditorGUI.Toggle(new Rect(startX, startY+spaceY-10, 20, height), indicatorFlags[0]);
					startY+=10;
					
					if(indicatorFlags[0]){
						GUI.Box(new Rect(startX, startY+spaceY-1, 175, 465+(rscCount*20)), "");
						startX+=3;
						
						EditorGUI.LabelField(new Rect(50+startX, startY+=spaceY, 200, height), "Level 1: ");
						
						
						if(rscCount!=towerList[index].baseStat.costs.Length){
							UpdateBaseStatCost(index, rscCount);
						}
						
						if(towerList[index].baseStat.costs.Length==1){
							EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cost: ");
							towerList[index].baseStat.costs[0] = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.costs[0]);
						}
						else{
							EditorGUI.LabelField(new Rect(startX, startY+=spaceY-5, 200, height), "Cost: ");
							for(int i=0; i<towerList[index].baseStat.costs.Length; i++){
								EditorGUI.LabelField(new Rect(startX, startY+spaceY-3, 200, height), " - resource: ");
								towerList[index].baseStat.costs[i] = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY-3, 50, height-2), towerList[index].baseStat.costs[i]);
							}
							startY+=8;
						}
						
						EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "BuildDuration: ");
						towerList[index].baseStat.buildDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.buildDuration);
						
						startY+=3;
						
						TypeDependentBaseStat(index);
						
						spaceY+=2;	startY+=8;
						
						//~ if(!(towerList[index].type==_TowerType.Mine || towerList[index].type==_TowerType.Block)){
							EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ShootObj: ");
							towerList[index].baseStat.shootObject=(Transform)EditorGUI.ObjectField(new Rect(startX+lW-30, startY+=spaceY, 100, height-2), towerList[index].baseStat.shootObject, typeof(Transform), false);
							
							EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "TurretObj: ");
							towerList[index].baseStat.turretObject=(Transform)EditorGUI.ObjectField(new Rect(startX+lW-30, startY+=spaceY, 100, height-2), towerList[index].baseStat.turretObject, typeof(Transform), false);
							
							EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "BaseObj: ");
							towerList[index].baseStat.baseObject=(Transform)EditorGUI.ObjectField(new Rect(startX+lW-30, startY+=spaceY, 100, height-2), towerList[index].baseStat.baseObject, typeof(Transform), false);
						
							//~ if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.DirectionalAOETower){
								//~ if(towerList[index].turretRotationModel==_RotationMode.SeparatedBarrel){
									//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "BarrelObj: ");
									//~ towerList[index].baseStat.barrelObject=(Transform)EditorGUI.ObjectField(new Rect(startX+lW-30, startY+=spaceY, 100, height-2), towerList[index].baseStat.barrelObject, typeof(Transform), false);
								//~ }
								//~ else startY+=spaceY;
							//~ }
							//~ else startY+=spaceY;
						//~ }
						
						//~ startY=870;
						startY+=10;
						startX-=3;
						
						//~ showAnimationList=EditorGUI.Foldout(new Rect(startX, startY+=spaceY, 300, 15), showAnimationList, showAnimationText);
						//~ if(showAnimationList){
							//~ towerList[index].buildAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - BuildAnimationBody: ", towerList[index].buildAnimationBody, typeof(Animation), false);
							//~ towerList[index].buildAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - BuildAnimation: ", towerList[index].buildAnimation, typeof(AnimationClip), false);
							//~ towerList[index].fireAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - FireAnimationBody: ", towerList[index].fireAnimationBody, typeof(Animation), false);
							//~ towerList[index].fireAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - FireAnimation: ", towerList[index].fireAnimation, typeof(AnimationClip), false);
							//~ towerList[index].fireAnimationBaseBody=(Animation)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - FireAnimationBaseBody: ", towerList[index].fireAnimationBaseBody, typeof(Animation), false);
							//~ towerList[index].fireAnimationBase=(AnimationClip)EditorGUI.ObjectField(new Rect(startX, startY+=spaceY, 300, 17), " - FireAnimationBase: ", towerList[index].fireAnimationBase, typeof(AnimationClip), false);
							
							
							
							//~ showAnimationText="Hide animation list";
							
						//~ if(!(towerList[index].type==_TowerType.Mine || towerList[index].type==_TowerType.Block)){
							spaceY-=3;
							GUI.Box(new Rect(startX, startY+spaceY-1, 175, 133), "");
							startX+=3;
							
							EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), "- Turret Fire Animation: ");
							EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Clip: ");
							towerList[index].baseStat.turretFireAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].baseStat.turretFireAnimation, typeof(AnimationClip), false);
							EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Component: ");
							towerList[index].baseStat.turretFireAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].baseStat.turretFireAnimationBody, typeof(Animation), false);
							startY+=10;
							
							EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), "- Base Fire Animation: ");
							EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Clip: ");
							towerList[index].baseStat.baseFireAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].baseStat.baseFireAnimation, typeof(AnimationClip), false);
							EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Component: ");
							towerList[index].baseStat.baseFireAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].baseStat.baseFireAnimationBody, typeof(Animation), false);
							startY+=10;
							
							//~ EditorGUI.LabelField(new Rect(startX+18, startY+=spaceY, 200, height), "Turret Build Animation: ");
							//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Clip: ");
							//~ towerList[index].baseStat.turretBuildAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].baseStat.turretBuildAnimation, typeof(AnimationClip), false);
							//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Component: ");
							//~ towerList[index].baseStat.turretBuildAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].baseStat.turretBuildAnimationBody, typeof(Animation), false);
							//~ startY+=10;
							
							//~ EditorGUI.LabelField(new Rect(startX+18, startY+=spaceY, 200, height), "Base Build Animation: ");
							//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Clip: ");
							//~ towerList[index].baseStat.baseBuildAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].baseStat.baseBuildAnimation, typeof(AnimationClip), false);
							//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Component: ");
							//~ towerList[index].baseStat.baseBuildAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].baseStat.baseBuildAnimationBody, typeof(Animation), false);
						//~ }	
							//EditorGUI.LabelField(new Rect(50+startX, startY+=spaceY, 200, height), "Level 1: ");
						//~ }
						//~ else{
							//~ showAnimationText="Show animation list";
						//~ }
						
						startX+=200;	startY=tabYPos;	spaceY=21;
						
					}
					else{
						EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), "1");
						startX+=35;	startY=tabYPos;	
					}
					
					for(int i=0; i<towerList[index].upgradeStat.Length; i++){
						
						if(towerList[index]!=null && towerList[index].upgradeStat[i]!=null){
						
							indicatorFlags[i+1] = EditorGUI.Toggle(new Rect(startX, startY+spaceY-10, 20, height), indicatorFlags[i+1]);
							startY+=10;
							
							if(indicatorFlags[i+1]){
								GUI.Box(new Rect(startX, startY+spaceY-1, 175, 465+(rscCount*20)), "");
								startX+=3;
								
								EditorGUI.LabelField(new Rect(50+startX, startY+=spaceY, 200, height), "Level "+(i+2).ToString()+": ");
								
								//EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cost: ");
								//towerList[index].upgradeStat[i].cost = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[i].cost);
								
								if(rscCount!=towerList[index].upgradeStat[i].costs.Length){
									UpdateUpgradeStatCost(index, rscCount);
								}
								
								if(towerList[index].upgradeStat[i].costs.Length==1){
									EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cost: ");
									towerList[index].upgradeStat[i].costs[0] = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[i].costs[0]);
								}
								else{
									EditorGUI.LabelField(new Rect(startX, startY+=spaceY-5, 200, height), "Cost: ");
									for(int j=0; j<towerList[index].upgradeStat[i].costs.Length; j++){
										EditorGUI.LabelField(new Rect(startX, startY+spaceY-3, 200, height), " - resource: ");
										towerList[index].upgradeStat[i].costs[j] = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY-3, 50, height-2), towerList[index].upgradeStat[i].costs[j]);
									}
									startY+=8;
								}
								
								
								EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "BuildDuration: ");
								towerList[index].upgradeStat[i].buildDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[i].buildDuration);
								startY+=3;
								
								TypeDependentUpgradeStat(index, i);
								
								spaceY+=2;	startY+=8;
								
								//~ if(!(towerList[index].type==_TowerType.Mine || towerList[index].type==_TowerType.Block)){
									EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ShootObj: ");
									towerList[index].upgradeStat[i].shootObject=(Transform)EditorGUI.ObjectField(new Rect(startX+lW-30, startY+=spaceY, 100, height-2), towerList[index].upgradeStat[i].shootObject, typeof(Transform), false);
									
									EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "TurretObj: ");
									towerList[index].upgradeStat[i].turretObject=(Transform)EditorGUI.ObjectField(new Rect(startX+lW-30, startY+=spaceY, 100, height-2), towerList[index].upgradeStat[i].turretObject, typeof(Transform), false);
									
									EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "BaseObj: ");
									towerList[index].upgradeStat[i].baseObject=(Transform)EditorGUI.ObjectField(new Rect(startX+lW-30, startY+=spaceY, 100, height-2), towerList[index].upgradeStat[i].baseObject, typeof(Transform), false);
									
									//~ if(towerList[index].type==_TowerType.TurretTower || towerList[index].type==_TowerType.DirectionalAOETower){
										//~ if(towerList[index].turretRotationModel==_RotationMode.SeparatedBarrel){
											//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "BarrelObj: ");
											//~ towerList[index].upgradeStat[i].barrelObject=(Transform)EditorGUI.ObjectField(new Rect(startX+lW-30, startY+=spaceY, 100, height-2), towerList[index].upgradeStat[i].barrelObject, typeof(Transform), false);
										//~ }
										//~ else startY+=spaceY;
									//~ }
									//~ else startY+=spaceY;
								//~ }
								
								
								//~ if(showAnimationList){
									//~ showAnimationText="Hide animation list";
									
								//~ if(!(towerList[index].type==_TowerType.Mine || towerList[index].type==_TowerType.Block)){
									spaceY-=3;
									startY+=10;//870+spaceY;
									startX-=3;
									
									//~ GUI.Box(new Rect(startX, startY+spaceY-1, 175, 275), "");
									GUI.Box(new Rect(startX, startY+spaceY-1, 175, 133), "");
									startX+=3;
									
									EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), "- Turret Fire Animation: ");
									EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Clip: ");
									towerList[index].upgradeStat[i].turretFireAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].upgradeStat[i].turretFireAnimation, typeof(AnimationClip), false);
									//EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Component: ");
									//towerList[index].upgradeStat[i].turretFireAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].upgradeStat[i].turretFireAnimationBody, typeof(Animation), false);
									startY+=10;
									
									EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), "Base Fire Animation: ");
									EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Clip: ");
									towerList[index].upgradeStat[i].baseFireAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].upgradeStat[i].baseFireAnimation, typeof(AnimationClip), false);
									//EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Component: ");
									//towerList[index].upgradeStat[i].baseFireAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].upgradeStat[i].baseFireAnimationBody, typeof(Animation), false);
									startY+=10;
									
									//~ EditorGUI.LabelField(new Rect(startX+18, startY+=spaceY, 200, height), "Turret Build Animation: ");
									//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Clip: ");
									//~ towerList[index].upgradeStat[i].turretBuildAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].upgradeStat[i].turretBuildAnimation, typeof(AnimationClip), false);
									//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Component: ");
									//~ towerList[index].upgradeStat[i].turretBuildAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].upgradeStat[i].turretBuildAnimationBody, typeof(Animation), false);
									//~ startY+=10;
									
									//~ EditorGUI.LabelField(new Rect(startX+18, startY+=spaceY, 200, height), "Base Build Animation: ");
									//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Clip: ");
									//~ towerList[index].upgradeStat[i].baseBuildAnimation=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].upgradeStat[i].baseBuildAnimation, typeof(AnimationClip), false);
									//~ EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Component: ");
									//~ towerList[index].upgradeStat[i].baseBuildAnimationBody=(Animation)EditorGUI.ObjectField(new Rect(startX+lW-25, startY+=spaceY, 95, height-2), towerList[index].upgradeStat[i].baseBuildAnimationBody, typeof(Animation), false);
								//~ }
									
									//EditorGUI.LabelField(new Rect(50+startX, startY+=spaceY, 200, height), "Level 1: ");
								//~ }
								
								startX+=190;
								startY=tabYPos;
								spaceY=21;
								
							}
							else{
								EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), (i+2).ToString());
								startX+=25;	startY=tabYPos;
							}
						}
					
					}
					
					
				//}
				
				HPAttributeEditor(index);
			}
			else{
				if(GUI.Button(new Rect(startX, startY, 140, height), "Find Build Manager")) GetTower();
				//return;
			}
			
			//~ if(towerList.Length>0) {
				
				
			//~ }
		}
	
		
		
		if(GUI.changed) EditorUtility.SetDirty(towerList[index]);
		
		GUI.EndScrollView();
    }
	
	
	
	
	
	
	
	void HPAttributeEditor(int index){
		float startY=133;
		float startX=320;
		
		float space=105;
		
		EditorGUI.LabelField(new Rect(startX, startY, 200, height), "Tower HP: ");
		towerList[index].HPAttribute.fullHP = EditorGUI.FloatField(new Rect(startX+space, startY, 50, height-2), towerList[index].HPAttribute.fullHP);
		
		//~ EditorGUI.LabelField(new Rect(startX, startY+20, 200, height), "Tower Shield: ");
		//~ towerList[index].HPAttribute.fullShield = EditorGUI.FloatField(new Rect(startX+space, startY+=20, 50, height-2), towerList[index].HPAttribute.fullShield);
		
		//~ if(towerList[index].HPAttribute.fullShield>0){
			//~ EditorGUI.LabelField(new Rect(startX, startY+20, 200, height), "Shield Recharge: ");
			//~ towerList[index].HPAttribute.shieldRechargeRate = EditorGUI.FloatField(new Rect(startX+space, startY+=20, 50, height-2), towerList[index].HPAttribute.shieldRechargeRate);
			
			//~ EditorGUI.LabelField(new Rect(startX, startY+20, 200, height), "Shield Stagger: ");
			//~ towerList[index].HPAttribute.shieldStagger = EditorGUI.FloatField(new Rect(startX+space, startY+=20, 50, height-2), towerList[index].HPAttribute.shieldStagger);
		//~ }
		
		startY=133;
		startX=320+105+50+10;
		space=100;
		
		EditorGUI.LabelField(new Rect(startX, startY, 200, height), "HP Overlay: ");
		towerList[index].HPAttribute.overlayHP=(Transform)EditorGUI.ObjectField(new Rect(startX+space, startY, 100, height-2), towerList[index].HPAttribute.overlayHP, typeof(Transform), false);
		
		//~ EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), "Shield Overlay: ");
		//~ towerList[index].HPAttribute.overlayShield=(Transform)EditorGUI.ObjectField(new Rect(startX+space, startY, 100, height-2), towerList[index].HPAttribute.overlayShield, typeof(Transform), false);
		
		EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), "Base Overlay: ");
		towerList[index].HPAttribute.overlayBase=(Transform)EditorGUI.ObjectField(new Rect(startX+space, startY, 100, height-2), towerList[index].HPAttribute.overlayBase, typeof(Transform), false);
		
		EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, height), "Always Show Overlay: ");
		towerList[index].HPAttribute.alwaysShowOverlay= EditorGUI.Toggle(new Rect(startX+space+40, startY, 100, height-2), towerList[index].HPAttribute.alwaysShowOverlay);
	}
	
	
	
	
	
	void TypeDependentBaseStat(int index){
		//turretTower
		if(towerType==0){
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+5, 200, height), "Damage: ");
			towerList[index].baseStat.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+5, 50, height-2), towerList[index].baseStat.damage);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cooldown: ");
			towerList[index].baseStat.cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.cooldown);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ReloadDuration: ");
			towerList[index].baseStat.reloadDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.reloadDuration);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ClipSize: ");
			towerList[index].baseStat.clipSize = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.clipSize);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Range: ");
			towerList[index].baseStat.range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.range);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "AoeRadius: ");
			towerList[index].baseStat.aoeRadius = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.aoeRadius);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "StunDuration: ");
			towerList[index].baseStat.stunDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.stunDuration);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Slow Effect: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].baseStat.slow.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.slow.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- SlowFactor: ");
			towerList[index].baseStat.slow.slowFactor = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.slow.slowFactor);
			
			spaceY+=3;
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "DamageOverTime: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].baseStat.dot.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.damage);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].baseStat.dot.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Interval: ");
			towerList[index].baseStat.dot.interval = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.interval);
			
			float ttDmg=towerList[index].baseStat.dot.damage*towerList[index].baseStat.dot.duration/towerList[index].baseStat.dot.interval;
			EditorGUI.LabelField(new Rect(startX+10, startY+=spaceY+3, 160, height), "TotalDamage:  "+ttDmg.ToString("f1"));
			
			spaceY+=3;
			//startY+=5;
			
		}
		//DirectionalAOETower
		else if(towerType==1){
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+5, 200, height), "Damage: ");
			towerList[index].baseStat.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+5, 50, height-2), towerList[index].baseStat.damage);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cooldown: ");
			towerList[index].baseStat.cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.cooldown);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Range: ");
			towerList[index].baseStat.range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.range);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "StunDuration: ");
			towerList[index].baseStat.stunDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.stunDuration);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Slow Effect: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].baseStat.slow.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.slow.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- SlowFactor: ");
			towerList[index].baseStat.slow.slowFactor = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.slow.slowFactor);
			
			spaceY+=3;
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "DamageOverTime: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].baseStat.dot.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.damage);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].baseStat.dot.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Interval: ");
			towerList[index].baseStat.dot.interval = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.interval);
			
			float ttDmg=towerList[index].baseStat.dot.damage*towerList[index].baseStat.dot.duration/towerList[index].baseStat.dot.interval;
			EditorGUI.LabelField(new Rect(startX+10, startY+=spaceY+3, 160, height), "TotalDamage:  "+ttDmg.ToString("f1"));
			
			spaceY+=3;
		}
		//AOETower
		else if(towerType==2){
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+5, 200, height), "Damage: ");
			towerList[index].baseStat.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+5, 50, height-2), towerList[index].baseStat.damage);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cooldown: ");
			towerList[index].baseStat.cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.cooldown);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ReloadDuration: ");
			towerList[index].baseStat.reloadDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.reloadDuration);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ClipSize: ");
			towerList[index].baseStat.clipSize = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.clipSize);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Range: ");
			towerList[index].baseStat.range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.range);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "StunDuration: ");
			towerList[index].baseStat.stunDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.stunDuration);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Slow Effect: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].baseStat.slow.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.slow.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- SlowFactor: ");
			towerList[index].baseStat.slow.slowFactor = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.slow.slowFactor);
			
			spaceY+=3;
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "DamageOverTime: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].baseStat.dot.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.damage);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].baseStat.dot.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Interval: ");
			towerList[index].baseStat.dot.interval = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.interval);
			
			float ttDmg=towerList[index].baseStat.dot.damage*towerList[index].baseStat.dot.duration/towerList[index].baseStat.dot.interval;
			EditorGUI.LabelField(new Rect(startX+10, startY+=spaceY+3, 160, height), "TotalDamage:  "+ttDmg.ToString("f1"));
			
			spaceY+=3;
			//startY+=5;
			
		}
		//SupportTower
		else if(towerType==3){
			
			spaceY+=5;
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Effective Range: ");
			towerList[index].baseStat.range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.range);
			
			spaceY+=5;
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Buff Effect: ");
			spaceY-=5;
			startY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].baseStat.buff.damageBuff = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.buff.damageBuff);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Cooldown: ");
			towerList[index].baseStat.buff.cooldownBuff = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.buff.cooldownBuff);
			towerList[index].baseStat.buff.cooldownBuff = Mathf.Clamp(towerList[index].baseStat.buff.cooldownBuff, -0.8f, 0.8f);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Range: ");
			towerList[index].baseStat.buff.rangeBuff = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.buff.rangeBuff);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- RegenHP: ");
			towerList[index].baseStat.buff.regenHP = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+3, 50, height-2), towerList[index].baseStat.buff.regenHP);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+10, 200, height), "Cooldown: ");
			towerList[index].baseStat.cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+10, 50, height-2), towerList[index].baseStat.cooldown);
			
			spaceY-=5;
		}
		//ResourceTower
		else if(towerType==4){
			
			//EditorGUI.LabelField(new Rect(startX, startY+spaceY+10, 200, height), "IncomeValue: ");
			//towerList[index].baseStat.incomeValue = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY+10, 50, height-2), towerList[index].baseStat.incomeValue);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+10, 200, height), "Cooldown: ");
			towerList[index].baseStat.cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+10, 50, height-2), towerList[index].baseStat.cooldown);
			
			startY+=10;
			
			if(rscCount!=towerList[index].baseStat.incomes.Length){
				UpdateBaseStatIncomes(index, rscCount);
			}
			
			if(towerList[index].baseStat.incomes.Length==1){
				EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "resources:");
				towerList[index].baseStat.incomes[0] = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.incomes[0]);
			}
			else{
				EditorGUI.LabelField(new Rect(startX, startY+=spaceY-5, 200, height), "Resources Per CD:");
				for(int i=0; i<towerList[index].baseStat.incomes.Length; i++){
					EditorGUI.LabelField(new Rect(startX, startY+spaceY-3, 200, height), " - resource: ");
					towerList[index].baseStat.incomes[i] = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY-3, 50, height-2), towerList[index].baseStat.incomes[i]);
				}
				startY+=8;
			}
			
			
		}
		//mine
		else if(towerType==5){
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+5, 200, height), "Damage: ");
			towerList[index].baseStat.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+5, 50, height-2), towerList[index].baseStat.damage);
			
			if(!towerList[index].mineOneOff){
				EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cooldown: ");
				towerList[index].baseStat.cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.cooldown);
			}
				
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "EffectiveRange: ");
			towerList[index].baseStat.range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.range);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "StunDuration: ");
			towerList[index].baseStat.stunDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.stunDuration);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Slow Effect: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].baseStat.slow.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.slow.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- SlowFactor: ");
			towerList[index].baseStat.slow.slowFactor = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.slow.slowFactor);
			
			spaceY+=3;
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "DamageOverTime: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].baseStat.dot.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.damage);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].baseStat.dot.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Interval: ");
			towerList[index].baseStat.dot.interval = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].baseStat.dot.interval);
			
			float ttDmg=towerList[index].baseStat.dot.damage*towerList[index].baseStat.dot.duration/towerList[index].baseStat.dot.interval;
			EditorGUI.LabelField(new Rect(startX+10, startY+=spaceY+3, 160, height), "TotalDamage:  "+ttDmg.ToString("f1"));
		
			spaceY+=3;
		}
		
	}
	
	
	
	
	
	
	
	
	void TypeDependentUpgradeStat(int index, int lvl){
		if(towerType==0){
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+5, 200, height), "Damage: ");
			towerList[index].upgradeStat[lvl].damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+5, 50, height-2), towerList[index].upgradeStat[lvl].damage);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cooldown: ");
			towerList[index].upgradeStat[lvl].cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].cooldown);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ReloadDuration: ");
			towerList[index].upgradeStat[lvl].reloadDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].reloadDuration);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ClipSize: ");
			towerList[index].upgradeStat[lvl].clipSize = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].clipSize);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Range: ");
			towerList[index].upgradeStat[lvl].range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].range);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "AoeRadius: ");
			towerList[index].upgradeStat[lvl].aoeRadius = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].aoeRadius);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "StunDuration: ");
			towerList[index].upgradeStat[lvl].stunDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].stunDuration);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Slow Effect: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].upgradeStat[lvl].slow.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].slow.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- SlowFactor: ");
			towerList[index].upgradeStat[lvl].slow.slowFactor = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].slow.slowFactor);
			
			spaceY+=3;
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "DamageOverTime: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].upgradeStat[lvl].dot.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.damage);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].upgradeStat[lvl].dot.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Interval: ");
			towerList[index].upgradeStat[lvl].dot.interval = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.interval);
			
			float ttDmg=towerList[index].baseStat.dot.damage*towerList[index].baseStat.dot.duration/towerList[index].baseStat.dot.interval;
			EditorGUI.LabelField(new Rect(startX+10, startY+=spaceY+3, 160, height), "TotalDamage:  "+ttDmg.ToString("f1"));
			
			spaceY+=3;
			//startY+=5;
			
		}
		else if(towerType==1){
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+5, 200, height), "Damage: ");
			towerList[index].upgradeStat[lvl].damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+5, 50, height-2), towerList[index].upgradeStat[lvl].damage);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cooldown: ");
			towerList[index].upgradeStat[lvl].cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].cooldown);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Range: ");
			towerList[index].upgradeStat[lvl].range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].range);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "StunDuration: ");
			towerList[index].upgradeStat[lvl].stunDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].stunDuration);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Slow Effect: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].upgradeStat[lvl].slow.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].slow.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- SlowFactor: ");
			towerList[index].upgradeStat[lvl].slow.slowFactor = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].slow.slowFactor);
			
			spaceY+=3;
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "DamageOverTime: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].upgradeStat[lvl].dot.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.damage);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].upgradeStat[lvl].dot.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Interval: ");
			towerList[index].upgradeStat[lvl].dot.interval = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.interval);
			
			float ttDmg=towerList[index].baseStat.dot.damage*towerList[index].baseStat.dot.duration/towerList[index].baseStat.dot.interval;
			EditorGUI.LabelField(new Rect(startX+10, startY+=spaceY+3, 160, height), "TotalDamage:  "+ttDmg.ToString("f1"));
			
			spaceY+=3;
		}
		else if(towerType==2){
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+5, 200, height), "Damage: ");
			towerList[index].upgradeStat[lvl].damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+5, 50, height-2), towerList[index].upgradeStat[lvl].damage);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Cooldown: ");
			towerList[index].upgradeStat[lvl].cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].cooldown);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ReloadDuration: ");
			towerList[index].upgradeStat[lvl].reloadDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].reloadDuration);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "ClipSize: ");
			towerList[index].upgradeStat[lvl].clipSize = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].clipSize);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Range: ");
			towerList[index].upgradeStat[lvl].range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].range);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "StunDuration: ");
			towerList[index].upgradeStat[lvl].stunDuration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].stunDuration);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Slow Effect: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].upgradeStat[lvl].slow.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].slow.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- SlowFactor: ");
			towerList[index].upgradeStat[lvl].slow.slowFactor = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].slow.slowFactor);
			
			spaceY+=3;
			
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "DamageOverTime: ");
			spaceY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].upgradeStat[lvl].dot.damage = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.damage);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Duration: ");
			towerList[index].upgradeStat[lvl].dot.duration = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.duration);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Interval: ");
			towerList[index].upgradeStat[lvl].dot.interval = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].dot.interval);
			
			float ttDmg=towerList[index].upgradeStat[lvl].dot.damage*towerList[index].upgradeStat[lvl].dot.duration/towerList[index].upgradeStat[lvl].dot.interval;
			EditorGUI.LabelField(new Rect(startX+10, startY+=spaceY+3, 160, height), "TotalDamage:  "+ttDmg.ToString("f1"));
			
			spaceY+=3;
			//startY+=5;
			
		}
		else if(towerType==3){
			
			spaceY+=5;
			EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "Effective Range: ");
			towerList[index].upgradeStat[lvl].range = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].range);
			
			spaceY+=5;
			EditorGUI.LabelField(new Rect(startX, startY+=spaceY+3, 200, height), "Buff Effect: ");
			spaceY-=5;
			startY-=3;
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Damage: ");
			towerList[index].upgradeStat[lvl].buff.damageBuff = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].buff.damageBuff);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Cooldown: ");
			towerList[index].upgradeStat[lvl].buff.cooldownBuff = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].buff.cooldownBuff);
			towerList[index].upgradeStat[lvl].buff.cooldownBuff = Mathf.Clamp(towerList[index].upgradeStat[lvl].buff.cooldownBuff, -0.8f, 0.8f);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- Range: ");
			towerList[index].upgradeStat[lvl].buff.rangeBuff = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].buff.rangeBuff);
			
			EditorGUI.LabelField(new Rect(startX+10, startY+spaceY, 200, height), "- RegenHP: ");
			towerList[index].upgradeStat[lvl].buff.regenHP = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+3, 50, height-2), towerList[index].upgradeStat[lvl].buff.regenHP);
			
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+10, 200, height), "Cooldown: ");
			towerList[index].upgradeStat[lvl].cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+10, 50, height-2), towerList[index].upgradeStat[lvl].cooldown);
		
			spaceY-=5;
		}
		else if(towerType==4){
			
			//EditorGUI.LabelField(new Rect(startX, startY+spaceY+10, 200, height), "Income Value: ");
			//towerList[index].upgradeStat[lvl].incomeValue = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY+10, 50, height-2), towerList[index].upgradeStat[lvl].incomeValue);
			
			EditorGUI.LabelField(new Rect(startX, startY+spaceY+10, 200, height), "Cooldown: ");
			towerList[index].upgradeStat[lvl].cooldown = EditorGUI.FloatField(new Rect(startX+lW, startY+=spaceY+10, 50, height-2), towerList[index].upgradeStat[lvl].cooldown);
		
			startY+=10;
			
			if(rscCount!=towerList[index].upgradeStat[lvl].incomes.Length){
				UpdateUpgradeStatIncomes(index, rscCount);
			}
			
			if(towerList[index].upgradeStat[lvl].incomes.Length==1){
				EditorGUI.LabelField(new Rect(startX, startY+spaceY, 200, height), "resources:");
				towerList[index].upgradeStat[lvl].incomes[0] = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY, 50, height-2), towerList[index].upgradeStat[lvl].incomes[0]);
			}
			else{
				EditorGUI.LabelField(new Rect(startX, startY+=spaceY-5, 200, height), "Resources Per CD:");
				for(int i=0; i<towerList[index].upgradeStat[lvl].incomes.Length; i++){
					EditorGUI.LabelField(new Rect(startX, startY+spaceY-3, 200, height), " - resource: ");
					towerList[index].upgradeStat[lvl].incomes[i] = EditorGUI.IntField(new Rect(startX+lW, startY+=spaceY-3, 50, height-2), towerList[index].upgradeStat[lvl].incomes[i]);
				}
				startY+=8;
			}
		
		}
		
	}
	
	void UpdateIndicatorFlags(int size){
		if(indicatorFlags.Length!=size){
			indicatorFlags=new bool[size];
			for(int i=0; i<indicatorFlags.Length; i++) indicatorFlags[i]=true;
		}
	}
	
	
	void UpdateBaseStatIncomes(int id, int length){
		int[] tempIncList=towerList[index].baseStat.incomes;
		
		towerList[index].baseStat.incomes=new int[length];
		
		for(int i=0; i<length; i++){
			if(i>=tempIncList.Length){
				towerList[index].baseStat.incomes[i]=0;
			}
			else{
				towerList[index].baseStat.incomes[i]=tempIncList[i];
			}
		}
	}
	
	void UpdateUpgradeStatIncomes(int id, int length){
		for(int j=0; j<towerList[index].upgradeStat.Length; j++){
			int[] tempIncList=towerList[index].upgradeStat[j].incomes;
			
			towerList[index].upgradeStat[j].incomes=new int[length];
			
			for(int i=0; i<length; i++){
				if(i>=tempIncList.Length){
					towerList[index].upgradeStat[j].incomes[i]=0;
				}
				else{
					towerList[index].upgradeStat[j].incomes[i]=tempIncList[i];
				}
			}
		}
	}
	
	void UpdateBaseStatCost(int id, int length){
		int[] tempCostList=towerList[index].baseStat.costs;
		
		towerList[index].baseStat.costs=new int[length];
		


Please complete the code given below. 
using System;
using Server.Items;
namespace Server.Engines.Craft
{
	public class DefBlacksmithy : CraftSystem
	{
		public override SkillName MainSkill
		{
			get	{ return SkillName.Blacksmith;	}
		}
		public override int GumpTitleNumber
		{
			get { return 1044002; } // <CENTER>BLACKSMITHY MENU</CENTER>
		}
		private static CraftSystem m_CraftSystem;
		public static CraftSystem CraftSystem
		{
			get
			{
				if ( m_CraftSystem == null )
					m_CraftSystem = new DefBlacksmithy();
				return m_CraftSystem;
			}
		}
		public override CraftECA ECA{ get{ return CraftECA.ChanceMinusSixtyToFourtyFive; } }
		public override double GetChanceAtMin( CraftItem item )
		{
			return 0.0; // 0%
		}
		private DefBlacksmithy() : base( 1, 1, 1.25 )// base( 1, 2, 1.7 )
		{
			/*
			
			base( MinCraftEffect, MaxCraftEffect, Delay )
			
			MinCraftEffect	: The minimum number of time the mobile will play the craft effect
			MaxCraftEffect	: The maximum number of time the mobile will play the craft effect
			Delay			: The delay between each craft effect
			
			Example: (3, 6, 1.7) would make the mobile do the PlayCraftEffect override
			function between 3 and 6 time, with a 1.7 second delay each time.
			
			*/ 
		}
		private static Type typeofAnvil = typeof( AnvilAttribute );
		private static Type typeofForge = typeof( ForgeAttribute );
		public static void CheckAnvilAndForge( Mobile from, int range, out bool anvil, out bool forge )
		{
			anvil = false;
			forge = false;
			Map map = from.Map;
			if ( map == null )
				return;
			IPooledEnumerable eable = map.GetItemsInRange( from.Location, range );
			foreach ( Item item in eable )
			{
				Type type = item.GetType();
				bool isAnvil = ( type.IsDefined( typeofAnvil, false ) || item.ItemID == 4015 || item.ItemID == 4016 || item.ItemID == 0x2DD5 || item.ItemID == 0x2DD6 );
				bool isForge = ( type.IsDefined( typeofForge, false ) || item.ItemID == 4017 || (item.ItemID >= 6522 && item.ItemID <= 6569) || item.ItemID == 0x2DD8 );
				if ( isAnvil || isForge )
				{
					if ( (from.Z + 16) < item.Z || (item.Z + 16) < from.Z || !from.InLOS( item ) )
						continue;
					anvil = anvil || isAnvil;
					forge = forge || isForge;
					if ( anvil && forge )
						break;
				}
			}
			eable.Free();
			for ( int x = -range; (!anvil || !forge) && x <= range; ++x )
			{
				for ( int y = -range; (!anvil || !forge) && y <= range; ++y )
				{
					StaticTile[] tiles = map.Tiles.GetStaticTiles( from.X+x, from.Y+y, true );
					for ( int i = 0; (!anvil || !forge) && i < tiles.Length; ++i )
					{
						int id = tiles[i].ID;
						bool isAnvil = ( id == 4015 || id == 4016 || id == 0x2DD5 || id == 0x2DD6 );
						bool isForge = ( id == 4017 || (id >= 6522 && id <= 6569) || id == 0x2DD8 );
						if ( isAnvil || isForge )
						{
							if ( (from.Z + 16) < tiles[i].Z || (tiles[i].Z + 16) < from.Z || !from.InLOS( new Point3D( from.X+x, from.Y+y, tiles[i].Z + (tiles[i].Height/2) + 1 ) ) )
								continue;
							anvil = anvil || isAnvil;
							forge = forge || isForge;
						}
					}
				}
			}
		}
		public override int CanCraft( Mobile from, BaseTool tool, Type itemType )
		{
			if ( tool == null || tool.Deleted || tool.UsesRemaining < 0 )
				return 1044038; // You have worn out your tool!
			else if ( !BaseTool.CheckTool( tool, from ) )
				return 1048146; // If you have a tool equipped, you must use that tool.
			else if ( !BaseTool.CheckAccessible( tool, from ) )
				return 1044263; // The tool must be on your person to use.
			bool anvil, forge;
			CheckAnvilAndForge( from, 2, out anvil, out forge );
			if ( anvil && forge )
				return 0;
			return 1044267; // You must be near an anvil and a forge to smith items.
		}
		public override void PlayCraftEffect( Mobile from )
		{
			// no animation, instant sound
			//if ( from.Body.Type == BodyType.Human && !from.Mounted )
			//	from.Animate( 9, 5, 1, true, false, 0 );
			//new InternalTimer( from ).Start();
			from.PlaySound( 0x2A );
		}
		// Delay to synchronize the sound with the hit on the anvil
		private class InternalTimer : Timer
		{
			private Mobile m_From;
			public InternalTimer( Mobile from ) : base( TimeSpan.FromSeconds( 0.7 ) )
			{
				m_From = from;
			}
			protected override void OnTick()
			{
				m_From.PlaySound( 0x2A );
			}
		}
		public override int PlayEndingEffect( Mobile from, bool failed, bool lostMaterial, bool toolBroken, int quality, bool makersMark, CraftItem item )
		{
			if ( toolBroken )
				from.SendLocalizedMessage( 1044038 ); // You have worn out your tool
			if ( failed )
			{
				if ( lostMaterial )
					return 1044043; // You failed to create the item, and some of your materials are lost.
				else
					return 1044157; // You failed to create the item, but no materials were lost.
			}
			else
			{
				if ( quality == 0 )
					return 502785; // You were barely able to make this item.  It's quality is below average.
				else if ( makersMark && quality == 2 )
					return 1044156; // You create an exceptional quality item and affix your maker's mark.
				else if ( quality == 2 )
					return 1044155; // You create an exceptional quality item.
				else				
					return 1044154; // You create the item.
			}
		}
		public override void InitCraftList()
		{
			/*
			Synthax for a SIMPLE craft item
			AddCraft( ObjectType, Group, MinSkill, MaxSkill, ResourceType, Amount, Message )
			
			ObjectType		: The type of the object you want to add to the build list.
			Group			: The group in wich the object will be showed in the craft menu.
			MinSkill		: The minimum of skill value
			MaxSkill		: The maximum of skill value
			ResourceType	: The type of the resource the mobile need to create the item
			Amount			: The amount of the ResourceType it need to create the item
			Message			: String or Int for Localized.  The message that will be sent to the mobile, if the specified resource is missing.
			
			Synthax for a COMPLEXE craft item.  A complexe item is an item that need either more than
			only one skill, or more than only one resource.
			
			Coming soon....
			*/
			#region Ringmail
			AddCraft( typeof( RingmailGloves ), 1011076, 1025099, 12.0, 62.0, typeof( IronIngot ), 1044036, 10, 1044037 );
			AddCraft( typeof( RingmailLegs ), 1011076, 1025104, 19.4, 69.4, typeof( IronIngot ), 1044036, 16, 1044037 );
			AddCraft( typeof( RingmailArms ), 1011076, 1025103, 16.9, 66.9, typeof( IronIngot ), 1044036, 14, 1044037 );
			AddCraft( typeof( RingmailChest ), 1011076, 1025100, 21.9, 71.9, typeof( IronIngot ), 1044036, 18, 1044037 );
			#endregion
			#region Chainmail
			AddCraft( typeof( ChainCoif ), 1011077, 1025051, 14.5, 64.5, typeof( IronIngot ), 1044036, 10, 1044037 );
			AddCraft( typeof( ChainLegs ), 1011077, 1025054, 36.7, 86.7, typeof( IronIngot ), 1044036, 18, 1044037 );
			AddCraft( typeof( ChainChest ), 1011077, 1025055, 39.1, 89.1, typeof( IronIngot ), 1044036, 20, 1044037 );
			#endregion
			int index = -1;
			#region Platemail
			AddCraft( typeof( PlateArms ), 1011078, 1025136, 66.3, 116.3, typeof( IronIngot ), 1044036, 18, 1044037 );
			AddCraft( typeof( PlateGloves ), 1011078, 1025140, 58.9, 108.9, typeof( IronIngot ), 1044036, 12, 1044037 );
			AddCraft( typeof( PlateGorget ), 1011078, 1025139, 56.4, 106.4, typeof( IronIngot ), 1044036, 10, 1044037 );
			AddCraft( typeof( PlateLegs ), 1011078, 1025137, 68.8, 118.8, typeof( IronIngot ), 1044036, 20, 1044037 );
			AddCraft( typeof( PlateChest ), 1011078, 1046431, 75.0, 125.0, typeof( IronIngot ), 1044036, 25, 1044037 );
			AddCraft( typeof( FemalePlateChest ), 1011078, 1046430, 44.1, 94.1, typeof( IronIngot ), 1044036, 20, 1044037 );
			if ( Core.AOS ) // exact pre-aos functionality unknown
				AddCraft( typeof( DragonBardingDeed ), 1011078, 1053012, 72.5, 122.5, typeof( IronIngot ), 1044036, 750, 1044037 );
			if( Core.SE )
			{
				index = AddCraft( typeof( PlateMempo ), 1011078, 1030180, 80.0, 130.0, typeof( IronIngot ), 1044036, 18, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( PlateDo ), 1011078, 1030184, 80.0, 130.0, typeof( IronIngot ), 1044036, 28, 1044037 ); //Double check skill
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( PlateHiroSode ), 1011078, 1030187, 80.0, 130.0, typeof( IronIngot ), 1044036, 16, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( PlateSuneate ), 1011078, 1030195, 65.0, 115.0, typeof( IronIngot ), 1044036, 20, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( PlateHaidate ), 1011078, 1030200, 65.0, 115.0, typeof( IronIngot ), 1044036, 20, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				
			}
			#endregion
			#region Helmets
			AddCraft( typeof( Bascinet ), 1011079, 1025132, 8.3, 58.3, typeof( IronIngot ), 1044036, 15, 1044037 );
			AddCraft( typeof( CloseHelm ), 1011079, 1025128, 37.9, 87.9, typeof( IronIngot ), 1044036, 15, 1044037 );
			AddCraft( typeof( Helmet ), 1011079, 1025130, 37.9, 87.9, typeof( IronIngot ), 1044036, 15, 1044037 );
			AddCraft( typeof( NorseHelm ), 1011079, 1025134, 37.9, 87.9, typeof( IronIngot ), 1044036, 15, 1044037 );
			AddCraft( typeof( PlateHelm ), 1011079, 1025138, 62.6, 112.6, typeof( IronIngot ), 1044036, 15, 1044037 );
			if( Core.SE )
			{
				index = AddCraft( typeof( ChainHatsuburi ), 1011079, 1030175, 30.0, 80.0, typeof( IronIngot ), 1044036, 20, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( PlateHatsuburi ), 1011079, 1030176, 45.0, 95.0, typeof( IronIngot ), 1044036, 20, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( HeavyPlateJingasa ), 1011079, 1030178, 45.0, 95.0, typeof( IronIngot ), 1044036, 20, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				
				index = AddCraft( typeof( LightPlateJingasa ), 1011079, 1030188, 45.0, 95.0, typeof( IronIngot ), 1044036, 20, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				
				index = AddCraft( typeof( SmallPlateJingasa ), 1011079, 1030191, 45.0, 95.0, typeof( IronIngot ), 1044036, 20, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( DecorativePlateKabuto ), 1011079, 1030179, 90.0, 140.0, typeof( IronIngot ), 1044036, 25, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				
				index = AddCraft( typeof( PlateBattleKabuto ), 1011079, 1030192, 90.0, 140.0, typeof( IronIngot ), 1044036, 25, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( StandardPlateKabuto ), 1011079, 1030196, 90.0, 140.0, typeof( IronIngot ), 1044036, 25, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				/*
				if( Core.ML )
				{
					index = AddCraft( typeof( Circlet ), 1011079, 1032645, 62.1, 112.1, typeof( IronIngot ), 1044036, 6, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( RoyalCirclet ), 1011079, 1032646, 70.0, 120.0, typeof( IronIngot ), 1044036, 6, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( GemmedCirclet ), 1011079, 1032647, 75.0, 125.0, typeof( IronIngot ), 1044036, 6, 1044037 );
					AddRes( index, typeof( Tourmaline ), 1044237, 1, 1044240 );
					AddRes( index, typeof( Amethyst ), 1044236, 1, 1044240 );
					AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 );
					SetNeededExpansion( index, Expansion.ML );
				}
				 * */
			}
			#endregion
			#region Shields
			AddCraft( typeof( Buckler ), 1011080, 1027027, -25.0, 25.0, typeof( IronIngot ), 1044036, 10, 1044037 );
			AddCraft( typeof( BronzeShield ), 1011080, 1027026, -15.2, 34.8, typeof( IronIngot ), 1044036, 12, 1044037 );
			AddCraft( typeof( HeaterShield ), 1011080, 1027030, 24.3, 74.3, typeof( IronIngot ), 1044036, 18, 1044037 );
			AddCraft( typeof( MetalShield ), 1011080, 1027035, -10.2, 39.8, typeof( IronIngot ), 1044036, 14, 1044037 );
			AddCraft( typeof( MetalKiteShield ), 1011080, 1027028, 4.6, 54.6, typeof( IronIngot ), 1044036, 16, 1044037 );
			AddCraft( typeof( WoodenKiteShield ), 1011080, 1027032, -15.2, 34.8, typeof( IronIngot ), 1044036, 8, 1044037 );
			if ( Core.AOS )
			{
				AddCraft( typeof( ChaosShield ), 1011080, 1027107, 85.0, 135.0, typeof( IronIngot ), 1044036, 25, 1044037 );
				AddCraft( typeof( OrderShield ), 1011080, 1027108, 85.0, 135.0, typeof( IronIngot ), 1044036, 25, 1044037 );
			}
			#endregion
			#region Bladed
			if ( Core.AOS )
				AddCraft( typeof( BoneHarvester ), 1011081, 1029915, 33.0, 83.0, typeof( IronIngot ), 1044036, 10, 1044037 );
			AddCraft( typeof( Broadsword ), 1011081, 1023934, 35.4, 85.4, typeof( IronIngot ), 1044036, 10, 1044037 );
			if ( Core.AOS )
				AddCraft( typeof( CrescentBlade ), 1011081, 1029921, 45.0, 95.0, typeof( IronIngot ), 1044036, 14, 1044037 );
			AddCraft( typeof( Cutlass ), 1011081, 1025185, 24.3, 74.3, typeof( IronIngot ), 1044036, 8, 1044037 );
			AddCraft( typeof( Dagger ), 1011081, 1023921, -0.4, 49.6, typeof( IronIngot ), 1044036, 3, 1044037 );
			AddCraft( typeof( Katana ),1011081, 1025119, 44.1, 94.1, typeof( IronIngot ), 1044036, 8, 1044037 );
			AddCraft( typeof( Kryss ), 1011081, 1025121, 36.7, 86.7, typeof( IronIngot ), 1044036, 8, 1044037 );
			AddCraft( typeof( Longsword ), 1011081, 1023937, 28.0, 78.0, typeof( IronIngot ), 1044036, 12, 1044037 );
			AddCraft( typeof( Scimitar ), 1011081, 1025046, 31.7, 81.7, typeof( IronIngot ), 1044036, 10, 1044037 );
			AddCraft( typeof( VikingSword ), 1011081, 1025049, 24.3, 74.3, typeof( IronIngot ), 1044036, 14, 1044037 );
			if( Core.SE )
			{
				index = AddCraft( typeof( NoDachi ), 1011081, 1030221, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( Wakizashi ), 1011081, 1030223, 50.0, 100.0, typeof( IronIngot ), 1044036, 8, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( Lajatang ), 1011081, 1030226, 80.0, 130.0, typeof( IronIngot ), 1044036, 25, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( Daisho ), 1011081, 1030228, 60.0, 110.0, typeof( IronIngot ), 1044036, 15, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( Tekagi ), 1011081, 1030230, 55.0, 105.0, typeof( IronIngot ), 1044036, 12, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( Shuriken ), 1011081, 1030231, 45.0, 95.0, typeof( IronIngot ), 1044036, 5, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( Kama ), 1011081, 1030232, 40.0, 90.0, typeof( IronIngot ), 1044036, 14, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				index = AddCraft( typeof( Sai ), 1011081, 1030234, 50.0, 100.0, typeof( IronIngot ), 1044036, 12, 1044037 );
				SetNeededExpansion( index, Expansion.SE );
				/*
				if( Core.ML )
				{
					index = AddCraft( typeof( RadiantScimitar ), 1011081, 1031571, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( WarCleaver ), 1011081, 1031567, 70.0, 120.0, typeof( IronIngot ), 1044036, 18, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( ElvenSpellblade ), 1011081, 1031564, 70.0, 120.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( AssassinSpike ), 1011081, 1031565, 70.0, 120.0, typeof( IronIngot ), 1044036, 9, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( Leafblade ), 1011081, 1031566, 70.0, 120.0, typeof( IronIngot ), 1044036, 12, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( RuneBlade ), 1011081, 1031570, 70.0, 120.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( ElvenMachete ), 1011081, 1031573, 70.0, 120.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( RuneCarvingKnife ), 1011081, 1072915, 70.0, 120.0, typeof( IronIngot ), 1044036, 9, 1044037 );
					AddRes( index, typeof( DreadHornMane ), 1032682, 1, 1053098 );
					AddRes( index, typeof( Putrefication ), 1032678, 10, 1053098 );
					AddRes( index, typeof( Muculent ), 1032680, 10, 1053098 );
					AddRecipe( index, 0 );
					ForceNonExceptional( index );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( ColdForgedBlade ), 1011081, 1072916, 70.0, 120.0, typeof( IronIngot ), 1044036, 18, 1044037 );
					AddRes( index, typeof( GrizzledBones ), 1032684, 1, 1053098 );
					AddRes( index, typeof( Taint ), 1032684, 10, 1053098 );
					AddRes( index, typeof( Blight ), 1032675, 10, 1053098 );
					AddRecipe( index, 1 );
					ForceNonExceptional( index );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( OverseerSunderedBlade ), 1011081, 1072920, 70.0, 120.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( GrizzledBones ), 1032684, 1, 1053098 );
					AddRes( index, typeof( Blight ), 1032675, 10, 1053098 );
					AddRes( index, typeof( Scourge ), 1032677, 10, 1053098 );
					AddRecipe( index, 2 );
					ForceNonExceptional( index );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( LuminousRuneBlade ), 1011081, 1072922, 70.0, 120.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( GrizzledBones ), 1032684, 1, 1053098 );
					AddRes( index, typeof( Corruption ), 1032676, 10, 1053098 );
					AddRes( index, typeof( Putrefication ), 1032678, 10, 1053098 );
					AddRecipe( index, 3 );
					ForceNonExceptional( index );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( TrueSpellblade ), 1011081, 1073513, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 );
					AddRecipe( index, 4 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( IcySpellblade ), 1011081, 1073514, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					AddRes( index, typeof( Turquoise ), 1032691, 1, 1044240 );
					AddRecipe( index, 5 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( FierySpellblade ), 1011081, 1073515, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					AddRes( index, typeof( FireRuby ), 1032695, 1, 1044240 );
					AddRecipe( index, 6 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( SpellbladeOfDefense ), 1011081, 1073516, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 );
					AddRes( index, typeof( WhitePearl ), 1032694, 1, 1044240 );
					AddRecipe( index, 7 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( TrueAssassinSpike ), 1011081, 1073517, 75.0, 125.0, typeof( IronIngot ), 1044036, 9, 1044037 );
					AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 );
					AddRecipe( index, 8 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( ChargedAssassinSpike ), 1011081, 1073518, 75.0, 125.0, typeof( IronIngot ), 1044036, 9, 1044037 );
					AddRes( index, typeof( EcruCitrine ), 1032693, 1, 1044240 );
					AddRecipe( index, 9 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( MagekillerAssassinSpike ), 1011081, 1073519, 75.0, 125.0, typeof( IronIngot ), 1044036, 9, 1044037 );
					AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 );
					AddRecipe( index, 10 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( WoundingAssassinSpike ), 1011081, 1073520, 75.0, 125.0, typeof( IronIngot ), 1044036, 9, 1044037 );
					AddRes( index, typeof( PerfectEmerald ), 1032692, 1, 1044240 );
					AddRecipe( index, 11 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( TrueLeafblade ), 1011081, 1073521, 75.0, 125.0, typeof( IronIngot ), 1044036, 12, 1044037 );
					AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 );
					AddRecipe( index, 12 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( Luckblade ), 1011081, 1073522, 75.0, 125.0, typeof( IronIngot ), 1044036, 12, 1044037 );
					AddRes( index, typeof( WhitePearl ), 1032694, 1, 1044240 );
					AddRecipe( index, 13 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( MagekillerLeafblade ), 1011081, 1073523, 75.0, 125.0, typeof( IronIngot ), 1044036, 12, 1044037 );
					AddRes( index, typeof( FireRuby ), 1032695, 1, 1044240 );
					AddRecipe( index, 14 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( LeafbladeOfEase ), 1011081, 1073524, 75.0, 125.0, typeof( IronIngot ), 1044036, 12, 1044037 );
					AddRes( index, typeof( PerfectEmerald ), 1032692, 1, 1044240 );
					AddRecipe( index, 15 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( KnightsWarCleaver ), 1011081, 1073525, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 );
					AddRes( index, typeof( PerfectEmerald ), 1032692, 1, 1044240 );
					AddRecipe( index, 16 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( ButchersWarCleaver ), 1011081, 1073526, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 );
					AddRes( index, typeof( Turquoise ), 1032691, 1, 1044240 );
					AddRecipe( index, 17 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( SerratedWarCleaver ), 1011081, 1073527, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 );
					AddRes( index, typeof( EcruCitrine ), 1032693, 1, 1044240 );
					AddRecipe( index, 18 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( TrueWarCleaver ), 1011081, 1073528, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 );
					AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 );
					AddRecipe( index, 19 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( AdventurersMachete ), 1011081, 1073533, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					AddRes( index, typeof( WhitePearl ), 1032694, 1, 1044240 );
					AddRecipe( index, 20 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( OrcishMachete ), 1011081, 1073534, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					AddRes( index, typeof( Scourge ), 1072136, 1, 1042081 );
					AddRecipe( index, 21 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( MacheteOfDefense ), 1011081, 1073535, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 );
					AddRecipe( index, 22 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( DiseasedMachete ), 1011081, 1073536, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 );
					AddRes( index, typeof( Blight ), 1072134, 1, 1042081 );
					AddRecipe( index, 23 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( RuneSabre ), 1011081, 1073537, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( Turquoise ), 1032691, 1, 1044240 );
					AddRecipe( index, 24 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( MagesRuneBlade ), 1011081, 1073538, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 );
					AddRecipe( index, 25 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( RuneBladeOfKnowledge ), 1011081, 1073539, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( EcruCitrine ), 1032693, 1, 1044240 );
					AddRecipe( index, 26 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( CorruptedRuneBlade ), 1011081, 1073540, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( Corruption ), 1072135, 1, 1042081 );
					AddRecipe( index, 27 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( TrueRadiantScimitar ), 1011081, 1073541, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 );
					AddRecipe( index, 28 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( DarkglowScimitar ), 1011081, 1073542, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 );
					AddRecipe( index, 29 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( IcyScimitar ), 1011081, 1073543, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 );
					AddRecipe( index, 30 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( TwinklingScimitar ), 1011081, 1073544, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
					AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 );
					AddRecipe( index, 31 );
					SetNeededExpansion( index, Expansion.ML );
					index = AddCraft( typeof( BoneMachete ), 1011081, 1020526, 75.0, 125.0, typeof( IronIngot ), 1044036, 20, 1044037 );
					AddRes( index, typeof( Bone ), 1049064, 6, 1049063 );
					AddRecipe( index, 32 );
					SetNeededExpansion( index, Expansion.ML );
				}
				*/
			}
			#endregion
			#region Axes
			AddCraft( typeof( Axe ), 1011082, 1023913, 34.2, 84.2, typeof( IronIngot ), 1044036, 14, 1044037 );
			AddCraft( typeof( BattleAxe ), 1011082, 1023911, 30.5, 80.5, typeof( IronIngot ), 1044036, 14, 1044037 );
			AddCraft( typeof( DoubleAxe ), 1011082, 1023915, 29.3, 79.3, typeof( IronIngot ), 1044036, 12, 1044037 );
			AddCraft( typeof( ExecutionersAxe ), 1011082, 1023909, 34.2, 84.2, typeof( IronIngot ), 1044036, 14, 1044037 );
			AddCraft( typeof( LargeBattleAxe ), 1011082, 1025115, 28.0, 78.0, typeof( IronIngot ), 1044036, 12, 1044037 );
			AddCraft( typeof( TwoHandedAxe ), 1011082, 1025187, 33.0, 83.0, typeof( IronIngot ), 1044036, 16, 1044037 );
			AddCraft( typeof( WarAxe ), 1011082, 1025040, 39.1, 89.1, typeof( IronIngot ), 1044036, 16, 1044037 );
			/*
			if( Core.ML )
			{
				index = AddCraft( typeof( OrnateAxe ), 1011082, 1031572, 70.0, 120.0, typeof( IronIngot ), 1044036, 18, 1044037 );
				SetNeededExpansion( index, Expansion.ML );
				index = AddCraft( typeof( GuardianAxe ), 1011082, 1073545, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );
				AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 );
				AddRecipe( index, 33 );
				SetNeededExpansion( index, Expansion.ML );
				index = AddCraft( typeof( SingingAxe ), 1011082, 1073546, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 );


Please complete the code given below. 
from io import BytesIO
from translate.convert import prop2po, test_convert
from translate.storage import po, properties
class TestProp2PO:
    @staticmethod
    def prop2po(propsource, proptemplate=None, personality="java"):
        """helper that converts .properties source to po source without requiring files"""
        inputfile = BytesIO(propsource.encode())
        inputprop = properties.propfile(inputfile, personality=personality)
        convertor = prop2po.prop2po(personality=personality)
        if proptemplate:
            templatefile = BytesIO(proptemplate.encode())
            templateprop = properties.propfile(templatefile)
            outputpo = convertor.mergestore(templateprop, inputprop)
        else:
            outputpo = convertor.convertstore(inputprop)
        return outputpo
    @staticmethod
    def convertprop(propsource):
        """call the convertprop, return the outputfile"""
        inputfile = BytesIO(propsource.encode())
        outputfile = BytesIO()
        templatefile = None
        assert prop2po.convertprop(inputfile, outputfile, templatefile)
        return outputfile.getvalue()
    @staticmethod
    def singleelement(pofile):
        """checks that the pofile contains a single non-header element, and returns it"""
        assert len(pofile.units) == 2
        assert pofile.units[0].isheader()
        print(pofile)
        return pofile.units[1]
    @staticmethod
    def countelements(pofile):
        """counts the number of non-header entries"""
        assert pofile.units[0].isheader()
        print(pofile)
        return len(pofile.units) - 1
    def test_simpleentry(self):
        """checks that a simple properties entry converts properly to a po entry"""
        propsource = "SAVEENTRY=Save file\n"
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.source == "Save file"
        assert pounit.target == ""
    def test_convertprop(self):
        """checks that the convertprop function is working"""
        propsource = "SAVEENTRY=Save file\n"
        posource = self.convertprop(propsource)
        pofile = po.pofile(BytesIO(posource))
        pounit = self.singleelement(pofile)
        assert pounit.source == "Save file"
        assert pounit.target == ""
    def test_no_value_entry(self):
        """checks that a properties entry without value is converted"""
        propsource = "KEY = \n"
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.getcontext() == "KEY"
        assert pounit.source == ""
        assert pounit.target == ""
    def test_no_separator_entry(self):
        """checks that a properties entry without separator is converted"""
        propsource = "KEY\n"
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.getcontext() == "KEY"
        assert pounit.source == ""
        assert pounit.target == ""
    def test_tab_at_end_of_string(self):
        """check that we preserve tabs at the end of a string"""
        propsource = r"TAB_AT_END=This setence has a tab at the end.\t"
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.source == "This setence has a tab at the end.\t"
        propsource = (
            r"SPACE_THEN_TAB_AT_END=This setence has a space then tab at the end. \t"
        )
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.source == "This setence has a space then tab at the end. \t"
        propsource = r"SPACE_AT_END=This setence will keep its 4 spaces at the end.    "
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.source == "This setence will keep its 4 spaces at the end.    "
        propsource = (
            r"SPACE_AT_END_NO_TRIM=This setence will keep its 4 spaces at the end.\    "
        )
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.source == "This setence will keep its 4 spaces at the end.    "
        propsource = r"SPACE_AT_END_NO_TRIM2=This setence will keep its 4 spaces at the end.\\    "
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.source == "This setence will keep its 4 spaces at the end.\\    "
    def test_tab_at_start_of_value(self):
        """check that tabs in a property are ignored where appropriate"""
        propsource = r"property	=	value"
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.getlocations()[0] == "property"
        assert pounit.source == "value"
    def test_unicode(self):
        """checks that unicode entries convert properly"""
        unistring = r"Norsk bokm\u00E5l"
        propsource = "nb = %s\n" % unistring
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        print(repr(pofile.units[0].target))
        print(repr(pounit.source))
        assert pounit.source == "Norsk bokm\u00E5l"
    def test_multiline_escaping(self):
        """checks that multiline enties can be parsed"""
        propsource = r"""5093=Unable to connect to your IMAP server. You may have exceeded the maximum number \
of connections to this server. If so, use the Advanced IMAP Server Settings dialog to \
reduce the number of cached connections."""
        pofile = self.prop2po(propsource)
        print(repr(pofile.units[1].target))
        assert self.countelements(pofile) == 1
    def test_comments(self):
        """test to ensure that we take comments from .properties and place them in .po"""
        propsource = """# Comment
prefPanel-smime=Security"""
        pofile = self.prop2po(propsource)
        pounit = self.singleelement(pofile)
        assert pounit.getnotes("developer") == "# Comment"
    def test_multiline_comments(self):
        """test to ensure that we handle multiline comments well"""
        propsource = """# Comment
# commenty 2
## @name GENERIC_ERROR
## @loc none
prefPanel-smime=
"""
        pofile = self.prop2po(propsource)
        print(bytes(pofile))
        # header comments:
        assert b"#. # Comment\n#. # commenty 2" in bytes(pofile)
        pounit = self.singleelement(pofile)
        assert pounit.getnotes("developer") == "## @name GENERIC_ERROR\n## @loc none"
    def test_folding_accesskeys(self):
        """check that we can fold various accesskeys into their associated label (bug #115)"""
        propsource = r"""cmd_addEngine.label = Add Engines...
cmd_addEngine.accesskey = A"""
        pofile = self.prop2po(propsource, personality="mozilla")
        pounit = self.singleelement(pofile)
        assert pounit.source == "&Add Engines..."
    def test_dont_translate(self):
        """check that we know how to ignore don't translate instructions in properties files (bug #116)"""
        propsource = """# LOCALIZATION NOTE (dont): DONT_TRANSLATE.
dont=don't translate me
do=translate me
"""
        pofile = self.prop2po(propsource)
        assert self.countelements(pofile) == 1
    def test_emptyproperty(self):
        """checks that empty property definitions survive into po file, bug 15"""
        for delimiter in ["=", ""]:
            propsource = "# comment\ncredit%s" % delimiter
            pofile = self.prop2po(propsource)
            pounit = self.singleelement(pofile)
            assert pounit.getlocations() == ["credit"]
            assert pounit.getcontext() == "credit"
            assert 'msgctxt "credit"' in str(pounit)
            assert b"#. # comment" in bytes(pofile)
            assert pounit.source == ""
    def test_emptyproperty_translated(self):
        """checks that if we translate an empty property it makes it into the PO"""
        for delimiter in ["=", ""]:
            proptemplate = "credit%s" % delimiter
            propsource = "credit=Translators Names"
            pofile = self.prop2po(propsource, proptemplate)
            pounit = self.singleelement(pofile)
            assert pounit.getlocations() == ["credit"]
            # FIXME we don't seem to get a _: comment but we should
            # assert pounit.getcontext() == "credit"
            assert pounit.source == ""
            assert pounit.target == "Translators Names"
    def test_newlines_in_value(self):
        """check that we can carry newlines that appear in the property value into the PO"""
        propsource = """prop=\\nvalue\\n\n"""
        pofile = self.prop2po(propsource)
        unit = self.singleelement(pofile)
        assert unit.source == "\nvalue\n"
    def test_header_comments(self):
        """check that we can handle comments not directly associated with a property"""
        propsource = """# Header comment\n\n# Comment\n\nprop=value\n"""
        pofile = self.prop2po(propsource)
        unit = self.singleelement(pofile)
        assert unit.source == "value"
        assert unit.getnotes("developer") == "# Comment"
    def test_unassociated_comment_order(self):
        """check that we can handle the order of unassociated comments"""
        propsource = """# Header comment\n\n# 1st Unassociated comment\n\n# 2nd Connected comment\nprop=value\n"""
        pofile = self.prop2po(propsource)
        unit = self.singleelement(pofile)
        assert unit.source == "value"
        assert (
            unit.getnotes("developer")
            == "# 1st Unassociated comment\n\n# 2nd Connected comment"
        )
    def test_x_header(self):
        """Test that we correctly create the custom header entries
        (accelerators, merge criterion).
        """
        propsource = """prop=value\n"""
        outputpo = self.prop2po(propsource, personality="mozilla")
        assert b"X-Accelerator-Marker" in bytes(outputpo)
        assert b"X-Merge-On" in bytes(outputpo)
        # Even though the gaia flavour inherrits from mozilla, it should not
        # get the header
        outputpo = self.prop2po(propsource, personality="gaia")
        assert b"X-Accelerator-Marker" not in bytes(outputpo)
        assert b"X-Merge-On" not in bytes(outputpo)
    def test_gaia_plurals(self):
        """Test conversion of gaia plural units."""
        propsource = """
message-multiedit-header={[ plural(n) ]}
message-multiedit-header[zero]=Edit
message-multiedit-header[one]={{ n }} selected
message-multiedit-header[two]={{ n }} selected
message-multiedit-header[few]={{ n }} selected
message-multiedit-header[many]={{ n }} selected
message-multiedit-header[other]={{ n }} selected
"""
        outputpo = self.prop2po(propsource, personality="gaia")
        pounit = outputpo.units[-1]
        assert pounit.hasplural()
        assert pounit.getlocations() == ["message-multiedit-header"]
        print(outputpo)
        zero_unit = outputpo.units[-2]
        assert not zero_unit.hasplural()
        assert zero_unit.source == "Edit"
    def test_successive_gaia_plurals(self):
        """Test conversion of two successive gaia plural units."""
        propsource = """
message-multiedit-header={[ plural(n) ]}
message-multiedit-header[zero]=Edit
message-multiedit-header[one]={{ n }} selected
message-multiedit-header[two]={{ n }} selected
message-multiedit-header[few]={{ n }} selected
message-multiedit-header[many]={{ n }} selected
message-multiedit-header[other]={{ n }} selected
message-multiedit-header2={[ plural(n) ]}
message-multiedit-header2[zero]=Edit 2
message-multiedit-header2[one]={{ n }} selected 2
message-multiedit-header2[two]={{ n }} selected 2
message-multiedit-header2[few]={{ n }} selected 2
message-multiedit-header2[many]={{ n }} selected 2
message-multiedit-header2[other]={{ n }} selected 2
"""
        outputpo = self.prop2po(propsource, personality="gaia")
        pounit = outputpo.units[-1]
        assert pounit.hasplural()
        assert pounit.getlocations() == ["message-multiedit-header2"]
        pounit = outputpo.units[-3]
        assert pounit.hasplural()
        assert pounit.getlocations() == ["message-multiedit-header"]
        print(outputpo)
        zero_unit = outputpo.units[-2]
        assert not zero_unit.hasplural()
        assert zero_unit.source == "Edit 2"
        zero_unit = outputpo.units[-4]
        assert not zero_unit.hasplural()
        assert zero_unit.source == "Edit"
    def test_duplicate_keys(self):
        """Check that we correctly handle duplicate keys."""
        source = """
key=value
key=value
"""
        po_file = self.prop2po(source)
        assert self.countelements(po_file) == 1
        po_unit = self.singleelement(po_file)
        assert po_unit.source == "value"
        source = """
key=value
key=another value
"""
        po_file = self.prop2po(source)
        assert self.countelements(po_file) == 2
        po_unit = po_file.units[1]
        assert po_unit.source == "value"
        assert po_unit.getlocations() == ["key"]
        po_unit = po_file.units[2]
        assert po_unit.source == "another value"
        assert po_unit.getlocations() == ["key"]
        source = """
key1=value
key2=value
"""
        po_file = self.prop2po(source)
        assert self.countelements(po_file) == 2
        po_unit = po_file.units[1]
        assert po_unit.source == "value"
        assert po_unit.getlocations() == ["key1"]
        po_unit = po_file.units[2]
        assert po_unit.source == "value"
        assert po_unit.getlocations() == ["key2"]
    def test_gwt_plurals(self):
        """Test conversion of gwt plural units."""
        propsource = """
message-multiedit-header={0,number} selected
message-multiedit-header[none]=Edit
message-multiedit-header[one]={0,number} selected
message-multiedit-header[two]={0,number} selected
message-multiedit-header[few]={0,number} selected
message-multiedit-header[many]={0,number} selected
"""
        outputpo = self.prop2po(propsource, personality="gwt")
        pounit = outputpo.units[-1]
        assert pounit.getlocations() == ["message-multiedit-header"]
class TestProp2POCommand(test_convert.TestConvertCommand, TestProp2PO):
    """Tests running actual prop2po commands on files"""
    convertmodule = prop2po
    defaultoptions = {"progress": "none"}
    def test_help(self, capsys):
        """tests getting help"""
        options = super().test_help(capsys)


Please complete the code given below. 
// GtkSharp.Generation.InterfaceGen.cs - The Interface Generatable.
//
// Author: Mike Kestner <mkestner@speakeasy.net>
//
// Copyright (c) 2001-2003 Mike Kestner
// Copyright (c) 2004, 2007 Novell, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
namespace GtkSharp.Generation {
	using System;
	using System.Collections;
	using System.IO;
	using System.Xml;
	public class InterfaceGen : ObjectBase {
		bool consume_only;
		ArrayList vms = new ArrayList ();
		ArrayList members = new ArrayList ();
		public InterfaceGen (XmlElement ns, XmlElement elem) : base (ns, elem) 
		{
			consume_only = elem.HasAttribute ("consume_only");
			foreach (XmlNode node in elem.ChildNodes) {
				switch (node.Name) {
				case "virtual_method":
					VirtualMethod vm = new VirtualMethod (node as XmlElement, this);
					vms.Add (vm);
					members.Add (vm);
					break;
				case "signal":
					object sig = sigs [(node as XmlElement).GetAttribute ("name")];
					if (sig == null)
						sig = new Signal (node as XmlElement, this);
					members.Add (sig);
					break;
				default:
					if (!IsNodeNameHandled (node.Name))
						Console.WriteLine ("Unexpected node " + node.Name + " in " + CName);
					break;
				}
			}
		}
		public bool IsConsumeOnly {
			get {
				return consume_only;
			}
		}
		public override string FromNative (string var, bool owned)
		{
			if (IsConsumeOnly)
				return "GLib.Object.GetObject (" + var + ", " + (owned ? "true" : "false") + ") as " + QualifiedName;
			else
				return QualifiedName + "Adapter.GetObject (" + var + ", " + (owned ? "true" : "false") + ")";
		}
		public override bool ValidateForSubclass ()
		{
			ArrayList invalids = new ArrayList ();
			foreach (Method method in methods.Values) {
				if (!method.Validate ()) {
					Console.WriteLine ("in type " + QualifiedName);
					invalids.Add (method);
				}
			}
			foreach (Method method in invalids)
				methods.Remove (method.Name);
			invalids.Clear ();
			return base.ValidateForSubclass ();
		}
		string IfaceName {
			get {
				return Name + "Iface";
			}
		}
		void GenerateIfaceStruct (StreamWriter sw)
		{
			sw.WriteLine ("\t\tstatic " + IfaceName + " iface;");
			sw.WriteLine ();
			sw.WriteLine ("\t\tstruct " + IfaceName + " {");
			sw.WriteLine ("\t\t\tpublic IntPtr gtype;");
			sw.WriteLine ("\t\t\tpublic IntPtr itype;");
			sw.WriteLine ();
			foreach (object member in members) {
				if (member is Signal) {
					Signal sig = member as Signal;
					sw.WriteLine ("\t\t\tpublic IntPtr {0};", sig.CName.Replace ("\"", "").Replace ("-", "_"));
				} else if (member is VirtualMethod) {
					VirtualMethod vm = member as VirtualMethod;
					bool has_target = methods [vm.Name] != null;
					if (!has_target)
						Console.WriteLine ("Interface " + QualifiedName + " virtual method " + vm.Name + " has no matching method to invoke.");
					string type = has_target && vm.IsValid ? vm.Name + "Delegate" : "IntPtr";
					sw.WriteLine ("\t\t\tpublic " + type + " " + vm.CName + ";");
				}
			}
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
		}
		void GenerateStaticCtor (StreamWriter sw)
		{
			sw.WriteLine ("\t\tstatic " + Name + "Adapter ()");
			sw.WriteLine ("\t\t{");
			sw.WriteLine ("\t\t\tGLib.GType.Register (_gtype, typeof({0}Adapter));", Name);
			foreach (VirtualMethod vm in vms) {
				bool has_target = methods [vm.Name] != null;
				if (has_target && vm.IsValid)
					sw.WriteLine ("\t\t\tiface.{0} = new {1}Delegate ({1}Callback);", vm.CName, vm.Name);
			}
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
		}
		void GenerateInitialize (StreamWriter sw)
		{
			sw.WriteLine ("\t\tstatic void Initialize (IntPtr ifaceptr, IntPtr data)");
			sw.WriteLine ("\t\t{");
			sw.WriteLine ("\t\t\t" + IfaceName + " native_iface = Marshal.PtrToStructure<" + IfaceName + "> (ifaceptr);");
			foreach (VirtualMethod vm in vms)
				sw.WriteLine ("\t\t\tnative_iface." + vm.CName + " = iface." + vm.CName + ";");
			sw.WriteLine ("\t\t\tMarshal.StructureToPtr<" + IfaceName + "> (native_iface, ifaceptr, false);");
			sw.WriteLine ("\t\t\tGCHandle gch = (GCHandle) data;");
			sw.WriteLine ("\t\t\tgch.Free ();");
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
		}
		void GenerateCallbacks (StreamWriter sw)
		{
			foreach (VirtualMethod vm in vms) {
				if (methods [vm.Name] != null) {
					sw.WriteLine ();
					vm.GenerateCallback (sw);
				}
			}
		}
		void GenerateCtors (StreamWriter sw)
		{
			sw.WriteLine ("\t\tpublic " + Name + "Adapter ()");
			sw.WriteLine ("\t\t{");
			sw.WriteLine ("\t\t\tInitHandler = new GLib.GInterfaceInitHandler (Initialize);");
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
			sw.WriteLine ("\t\t{0}Implementor implementor;", Name);
			sw.WriteLine ();
			sw.WriteLine ("\t\tpublic {0}Adapter ({0}Implementor implementor)", Name);
			sw.WriteLine ("\t\t{");
			sw.WriteLine ("\t\t\tif (implementor == null)");
			sw.WriteLine ("\t\t\t\tthrow new ArgumentNullException (\"implementor\");");
			sw.WriteLine ("\t\t\tthis.implementor = implementor;");
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
			sw.WriteLine ("\t\tpublic " + Name + "Adapter (IntPtr handle)");
			sw.WriteLine ("\t\t{");
			sw.WriteLine ("\t\t\tthis.handle = handle;");
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
		}
		void GenerateGType (StreamWriter sw)
		{
			Method m = GetMethod ("GetType");
			m.GenerateImport (sw);
			sw.WriteLine ("\t\tprivate static GLib.GType _gtype = new GLib.GType ({0} ());", m.CName);
			sw.WriteLine ();
			sw.WriteLine ("\t\tpublic override GLib.GType GType {");
			sw.WriteLine ("\t\t\tget {");
			sw.WriteLine ("\t\t\t\treturn _gtype;");
			sw.WriteLine ("\t\t\t}");
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
		}
		void GenerateHandleProp (StreamWriter sw)
		{
			sw.WriteLine ("\t\tIntPtr handle;");
			sw.WriteLine ("\t\tpublic override IntPtr Handle {");
			sw.WriteLine ("\t\t\tget {");
			sw.WriteLine ("\t\t\t\tif (handle != IntPtr.Zero)");
			sw.WriteLine ("\t\t\t\t\treturn handle;");
			sw.WriteLine ("\t\t\t\treturn implementor == null ? IntPtr.Zero : implementor.Handle;");
			sw.WriteLine ("\t\t\t}");
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
		}
		void GenerateGetObject (StreamWriter sw)
		{
			sw.WriteLine ("\t\tpublic static " + Name + " GetObject (IntPtr handle, bool owned)");
			sw.WriteLine ("\t\t{");
			sw.WriteLine ("\t\t\tGLib.Object obj = GLib.Object.GetObject (handle, owned);");
			sw.WriteLine ("\t\t\treturn GetObject (obj);");
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
			sw.WriteLine ("\t\tpublic static " + Name + " GetObject (GLib.Object obj)");
			sw.WriteLine ("\t\t{");
			sw.WriteLine ("\t\t\tif (obj == null)");
			sw.WriteLine ("\t\t\t\treturn null;");
			sw.WriteLine ("\t\t\telse if (obj is " + Name + "Implementor)");
			sw.WriteLine ("\t\t\t\treturn new {0}Adapter (obj as {0}Implementor);", Name);
			sw.WriteLine ("\t\t\telse if (obj as " + Name + " == null)");
			sw.WriteLine ("\t\t\t\treturn new {0}Adapter (obj.Handle);", Name);
			sw.WriteLine ("\t\t\telse");
			sw.WriteLine ("\t\t\t\treturn obj as {0};", Name);
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
		}
		void GenerateImplementorProp (StreamWriter sw)
		{
			sw.WriteLine ("\t\tpublic " + Name + "Implementor Implementor {");
			sw.WriteLine ("\t\t\tget {");
			sw.WriteLine ("\t\t\t\treturn implementor;");
			sw.WriteLine ("\t\t\t}");
			sw.WriteLine ("\t\t}");
			sw.WriteLine ();
		}
		void GenerateAdapter (GenerationInfo gen_info)
		{
			if (IsConsumeOnly)
				return;
			StreamWriter sw = gen_info.Writer = gen_info.OpenStream (Name + "Adapter");
			sw.WriteLine ("namespace " + NS + " {");
			sw.WriteLine ();
			sw.WriteLine ("\tusing System;");
			sw.WriteLine ("\tusing System.Runtime.InteropServices;");
			sw.WriteLine ();
			sw.WriteLine ("#region Autogenerated code");
			sw.WriteLine ("\tpublic class " + Name + "Adapter : GLib.GInterfaceAdapter, " + QualifiedName + " {");
			sw.WriteLine ();
			GenerateIfaceStruct (sw);
			GenerateStaticCtor (sw);
			GenerateCallbacks (sw);
			GenerateInitialize (sw);
			GenerateCtors (sw);
			GenerateGType (sw);
			GenerateHandleProp (sw);
			GenerateGetObject (sw);
			GenerateImplementorProp (sw);
			GenProperties (gen_info, null);
			foreach (Signal sig in sigs.Values)
				sig.GenEvent (sw, null, "GLib.Object.GetObject (Handle)");
			Method temp = methods ["GetType"] as Method;
			if (temp != null)
				methods.Remove ("GetType");
			GenMethods (gen_info, new Hashtable (), this);
			if (temp != null)
				methods ["GetType"] = temp;
			sw.WriteLine ("#endregion");
			AppendCustom (sw, gen_info.CustomDir, Name + "Adapter");
			sw.WriteLine ("\t}");
			sw.WriteLine ("}");
			sw.Close ();
			gen_info.Writer = null;
		}
		void GenerateImplementorIface (GenerationInfo gen_info)
		{
			StreamWriter sw = gen_info.Writer;
			if (IsConsumeOnly)
				return;
			sw.WriteLine ();
			sw.WriteLine ("\t[GLib.GInterface (typeof (" + Name + "Adapter))]");
			string access = IsInternal ? "internal" : "public";
			sw.WriteLine ("\t" + access + " interface " + Name + "Implementor : GLib.IWrapper {");
			sw.WriteLine ();
			Hashtable vm_table = new Hashtable ();
			foreach (VirtualMethod vm in vms)
				vm_table [vm.Name] = vm;
			foreach (VirtualMethod vm in vms) {
				if (vm_table [vm.Name] == null)
					continue;
				else if (!vm.IsValid) {
					vm_table.Remove (vm.Name);
					continue;
				} else if (vm.IsGetter || vm.IsSetter) {
					string cmp_name = (vm.IsGetter ? "Set" : "Get") + vm.Name.Substring (3);
					VirtualMethod cmp = vm_table [cmp_name] as VirtualMethod;
					if (cmp != null && (cmp.IsGetter || cmp.IsSetter)) {
						if (vm.IsSetter)
							cmp.GenerateDeclaration (sw, vm);
						else
							vm.GenerateDeclaration (sw, cmp);
						vm_table.Remove (cmp.Name);
					} else 
						vm.GenerateDeclaration (sw, null);
					vm_table.Remove (vm.Name);
				} else {
					vm.GenerateDeclaration (sw, null);
					vm_table.Remove (vm.Name);
				}
			}
			AppendCustom (sw, gen_info.CustomDir, Name + "Implementor");
			sw.WriteLine ("\t}");
		}
		public override void Generate (GenerationInfo gen_info)
		{
			GenerateAdapter (gen_info);
			StreamWriter sw = gen_info.Writer = gen_info.OpenStream (Name);
			sw.WriteLine ("namespace " + NS + " {");
			sw.WriteLine ();
			sw.WriteLine ("\tusing System;");
			sw.WriteLine ();
			sw.WriteLine ("#region Autogenerated code");
			string access = IsInternal ? "internal" : "public";
			sw.WriteLine ("\t" + access + " interface " + Name + " : GLib.IWrapper {");
			sw.WriteLine ();
			


Please complete the code given below. 
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
                    'supported_by': 'community',
                    'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_wireless_controller_inter_controller
short_description: Configure inter wireless controller operation in Fortinet's FortiOS and FortiGate.
description:
    - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
      user to set and modify wireless_controller feature and inter_controller category.
      Examples include all parameters and values need to be adjusted to datasources before usage.
      Tested with FOS v6.0.5
version_added: "2.9"
author:
    - Miguel Angel Munoz (@mamunozgonzalez)
    - Nicolas Thomas (@thomnico)
notes:
    - Requires fortiosapi library developed by Fortinet
    - Run as a local_action in your playbook
requirements:
    - fortiosapi>=0.9.8
options:
    host:
        description:
            - FortiOS or FortiGate IP address.
        type: str
        required: false
    username:
        description:
            - FortiOS or FortiGate username.
        type: str
        required: false
    password:
        description:
            - FortiOS or FortiGate password.
        type: str
        default: ""
    vdom:
        description:
            - Virtual domain, among those defined previously. A vdom is a
              virtual instance of the FortiGate that can be configured and
              used as a different unit.
        type: str
        default: root
    https:
        description:
            - Indicates if the requests towards FortiGate must use HTTPS protocol.
        type: bool
        default: true
    ssl_verify:
        description:
            - Ensures FortiGate certificate must be verified by a proper CA.
        type: bool
        default: true
    wireless_controller_inter_controller:
        description:
            - Configure inter wireless controller operation.
        default: null
        type: dict
        suboptions:
            fast_failover_max:
                description:
                    - Maximum number of retransmissions for fast failover HA messages between peer wireless controllers (3 - 64).
                type: int
            fast_failover_wait:
                description:
                    - Minimum wait time before an AP transitions from secondary controller to primary controller (10 - 86400 sec).
                type: int
            inter_controller_key:
                description:
                    - Secret key for inter-controller communications.
                type: str
            inter_controller_mode:
                description:
                    - Configure inter-controller mode (disable, l2-roaming, 1+1).
                type: str
                choices:
                    - disable
                    - l2-roaming
                    - 1+1
            inter_controller_peer:
                description:
                    - Fast failover peer wireless controller list.
                type: list
                suboptions:
                    id:
                        description:
                            - ID.
                        required: true
                        type: int
                    peer_ip:
                        description:
                            - Peer wireless controller's IP address.
                        type: str
                    peer_port:
                        description:
                            - Port used by the wireless controller's for inter-controller communications (1024 - 49150).
                        type: int
                    peer_priority:
                        description:
                            - Peer wireless controller's priority (primary or secondary).
                        type: str
                        choices:
                            - primary
                            - secondary
            inter_controller_pri:
                description:
                    - Configure inter-controller's priority (primary or secondary).
                type: str
                choices:
                    - primary
                    - secondary
'''
EXAMPLES = '''
- hosts: localhost
  vars:
   host: "192.168.122.40"
   username: "admin"
   password: ""
   vdom: "root"
   ssl_verify: "False"
  tasks:
  - name: Configure inter wireless controller operation.
    fortios_wireless_controller_inter_controller:
      host:  "{{ host }}"
      username: "{{ username }}"
      password: "{{ password }}"
      vdom:  "{{ vdom }}"
      https: "False"
      wireless_controller_inter_controller:
        fast_failover_max: "3"
        fast_failover_wait: "4"
        inter_controller_key: "<your_own_value>"
        inter_controller_mode: "disable"
        inter_controller_peer:
         -
            id:  "8"
            peer_ip: "<your_own_value>"
            peer_port: "10"
            peer_priority: "primary"
        inter_controller_pri: "primary"
'''
RETURN = '''
build:
  description: Build number of the fortigate image
  returned: always
  type: str
  sample: '1547'
http_method:
  description: Last method used to provision the content into FortiGate
  returned: always
  type: str
  sample: 'PUT'
http_status:
  description: Last result given by FortiGate on last operation applied
  returned: always
  type: str
  sample: "200"
mkey:
  description: Master key (id) used in the last call to FortiGate
  returned: success
  type: str
  sample: "id"
name:
  description: Name of the table used to fulfill the request
  returned: always
  type: str
  sample: "urlfilter"
path:
  description: Path of the table used to fulfill the request
  returned: always
  type: str
  sample: "webfilter"
revision:
  description: Internal revision number
  returned: always
  type: str
  sample: "17.0.2.10658"
serial:
  description: Serial number of the unit
  returned: always
  type: str
  sample: "FGVMEVYYQT3AB5352"
status:
  description: Indication of the operation's result
  returned: always
  type: str
  sample: "success"
vdom:
  description: Virtual domain used
  returned: always
  type: str
  sample: "root"
version:
  description: Version of the FortiGate
  returned: always
  type: str
  sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
    host = data['host']
    username = data['username']
    password = data['password']
    ssl_verify = data['ssl_verify']
    fos.debug('on')
    if 'https' in data and not data['https']:
        fos.https('off')
    else:
        fos.https('on')
    fos.login(host, username, password, verify=ssl_verify)
def filter_wireless_controller_inter_controller_data(json):
    option_list = ['fast_failover_max', 'fast_failover_wait', 'inter_controller_key',
                   'inter_controller_mode', 'inter_controller_peer', 'inter_controller_pri']
    dictionary = {}
    for attribute in option_list:
        if attribute in json and json[attribute] is not None:
            dictionary[attribute] = json[attribute]
    return dictionary
def underscore_to_hyphen(data):
    if isinstance(data, list):
        for elem in data:
            elem = underscore_to_hyphen(elem)
    elif isinstance(data, dict):
        new_data = {}
        for k, v in data.items():
            new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
        data = new_data
    return data
def wireless_controller_inter_controller(data, fos):
    vdom = data['vdom']
    wireless_controller_inter_controller_data = data['wireless_controller_inter_controller']
    filtered_data = underscore_to_hyphen(filter_wireless_controller_inter_controller_data(wireless_controller_inter_controller_data))
    return fos.set('wireless-controller',
                   'inter-controller',
                   data=filtered_data,
                   vdom=vdom)
def is_successful_status(status):
    return status['status'] == "success" or \
        status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_wireless_controller(data, fos):
    if data['wireless_controller_inter_controller']:
        resp = wireless_controller_inter_controller(data, fos)
    return not is_successful_status(resp), \
        resp['status'] == "success", \
        resp
def main():
    fields = {
        "host": {"required": False, "type": "str"},
        "username": {"required": False, "type": "str"},
        "password": {"required": False, "type": "str", "default": "", "no_log": True},
        "vdom": {"required": False, "type": "str", "default": "root"},
        "https": {"required": False, "type": "bool", "default": True},
        "ssl_verify": {"required": False, "type": "bool", "default": True},
        "wireless_controller_inter_controller": {
            "required": False, "type": "dict", "default": None,
            "options": {
                "fast_failover_max": {"required": False, "type": "int"},
                "fast_failover_wait": {"required": False, "type": "int"},
                "inter_controller_key": {"required": False, "type": "str", "no_log": True},
                "inter_controller_mode": {"required": False, "type": "str",
                                          "choices": ["disable", "l2-roaming", "1+1"]},
                "inter_controller_peer": {"required": False, "type": "list",
                                          "options": {
                                              "id": {"required": True, "type": "int"},
                                              "peer_ip": {"required": False, "type": "str"},
                                              "peer_port": {"required": False, "type": "int"},
                                              "peer_priority": {"required": False, "type": "str",
                                                                "choices": ["primary", "secondary"]}
                                          }},
                "inter_controller_pri": {"required": False, "type": "str",
                                         "choices": ["primary", "secondary"]}
            }
        }
    }


Please complete the code given below. 
/*
 * Copyright (c) 2012-2018 Red Hat, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Red Hat, Inc. - initial API and implementation
 */
package org.eclipse.che.ide.ui.smartTree;
import com.google.gwt.dom.client.Element;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.che.ide.ui.smartTree.data.MutableNode;
import org.eclipse.che.ide.ui.smartTree.data.Node;
/**
 * Node descriptor. Uses internally in the tree.
 *
 * @author Vlad Zhukovskiy
 */
public class NodeDescriptor {
  private NodeStorage nodeStorage;
  private Node node;
  private NodeDescriptor parent;
  private List<NodeDescriptor> children = new ArrayList<>();
  private boolean root;
  private String domId;
  private boolean childrenRendered;
  private boolean expand;
  private boolean expandDeep;
  private boolean expanded;
  private boolean loaded;
  private boolean loading;
  private Element rootContainerElement;
  private Element nodeContainerElement;
  private Element jointContainerElement;
  private Element iconContainerElement;
  private Element userElement;
  private Element presentableTextContainer;
  private Element infoTextContainer;
  private Element loadElement;
  private Element descendantsContainerElement;
  public NodeDescriptor(NodeStorage nodeStorage, Node node) {
    this.nodeStorage = nodeStorage;
    if (node == null) {
      root = true;
    }
    this.node = node;
  }
  protected void addChild(int index, NodeDescriptor child) {
    final int actualIndex;
    if (nodeStorage.isSorted()) {
      int insertPos = Collections.binarySearch(children, child, nodeStorage.buildFullComparator());
      actualIndex = insertPos < 0 ? (-insertPos - 1) : insertPos;
    } else {
      actualIndex = index;
    }
    children.add(actualIndex, child);
    child.parent = this;
  }
  public void addChildren(int index, List<NodeDescriptor> children) {
    if (nodeStorage.isSorted()) {
      getChildren().addAll(children);
      Collections.sort(getChildren(), nodeStorage.buildFullComparator());
    } else {
      int actualIndex = index == 0 ? 0 : (getChildren().indexOf(getChildren().get(index - 1)) + 1);
      getChildren().addAll(actualIndex, children);
    }
    for (NodeDescriptor child : children) {
      child.parent = this;
    }
  }
  public void clear() {
    children.clear();
  }
  public List<NodeDescriptor> getChildren() {
    return children;
  }
  public Node getNode() {
    return node;
  }
  public NodeDescriptor getParent() {
    return parent;
  }
  public void setNode(Node node) {
    this.node = node;
  }
  public void setParent(NodeDescriptor parent) {
    this.parent = parent;
  }
  public boolean isRoot() {
    return root;
  }
  public void remove(NodeDescriptor descriptor) {
    children.remove(descriptor);
  }
  public void reset() {
    expand = false;
    expanded = false;
    childrenRendered = false;
  }
  public void clearElements() {
    rootContainerElement = null;
    nodeContainerElement = null;
    jointContainerElement = null;
    iconContainerElement = null;
    userElement = null;
    presentableTextContainer = null;
    infoTextContainer = null;
    loadElement = null;
    descendantsContainerElement = null;
    //        domId = null;
  }
  public Element getDescendantsContainerElement() {
    return descendantsContainerElement;
  }
  public String getDomId() {
    return domId;
  }
  public Element getRootContainer() {
    return rootContainerElement;
  }
  public Element getNodeContainerElement() {
    return nodeContainerElement;
  }
  public Element getIconContainerElement() {
    return iconContainerElement;
  }
  public Element getJointContainerElement() {
    return jointContainerElement;
  }
  public Element getPresentableTextContainer() {
    return presentableTextContainer;
  }
  public Element getInfoTextContainer() {
    return infoTextContainer;
  }
  public boolean isChildrenRendered() {
    return childrenRendered;
  }
  public boolean isExpand() {
    return expand;
  }
  public boolean isExpandDeep() {
    return expandDeep;
  }
  public boolean isExpanded() {
    return expanded;
  }
  public boolean isLeaf() {
    return node.isLeaf();
  }
  public boolean isLoaded() {
    return loaded;
  }
  public boolean isLoading() {
    return loading;
  }
  public void setChildrenRendered(boolean childrenRendered) {
    this.childrenRendered = childrenRendered;
  }
  public void setDescendantsContainerElement(Element descendantsContainerElement) {
    this.descendantsContainerElement = descendantsContainerElement;
  }
  public void setNodeContainerElement(Element nodeContainerElement) {
    this.nodeContainerElement = nodeContainerElement;
  }
  public void setRootContainerElement(Element rootContainerElement) {
    this.rootContainerElement = rootContainerElement;
  }
  public void setExpand(boolean expand) {
    this.expand = expand;
  }
  public void setExpandDeep(boolean expandDeep) {
    this.expandDeep = expandDeep;
  }
  public void setExpanded(boolean expanded) {
    this.expanded = expanded;
  }
  public void setIconContainerElement(Element iconContainerElement) {
    this.iconContainerElement = iconContainerElement;
  }
  public void setJointContainerElement(Element jointContainerElement) {
    this.jointContainerElement = jointContainerElement;
  }
  public void setLeaf(boolean leaf) {


Please complete the code given below. 
using N2.Definitions.Static;
using N2.Details;
using N2.Engine;
using N2.Persistence;
using N2.Persistence.Sources;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace N2.Definitions
{
    public delegate ContentItem GroupFactoryDelegate(ContentItem parent, string title, string name, Func<IEnumerable<ContentItem>> childFactory);
    public class GroupChildrenAttribute : Attribute, IInjectable<DefinitionMap>
    {
        public GroupChildrenAttribute()
            : this(GroupChildrenMode.Pages)
        {
        }
        public GroupChildrenAttribute(GroupChildrenMode groupBy)
        {
            GroupBy = groupBy;
            AllowDirectQuery = true;
            PageSize = 25;
            StartPagingTreshold = 100;
            DaysBeforeArchived = 365;
	        MinGroupSize = 1;
        }
        private DefinitionMap map;
        protected DefinitionMap Map
        {
            get { return map ?? (map = Context.Current.Resolve<DefinitionMap>()); }
            set { map = value; }
        }
        public GroupChildrenMode GroupBy { get; set; }
        public int StartPagingTreshold { get; set; }
        public int PageSize { get; set; }
        public int DaysBeforeArchived { get; set; }
        public bool AllowDirectQuery { get; set; }
		/// <summary>
		/// Minimum size for a single group. If there aren't enough similar items to form a group, then those items won't be grouped and will instead be shown individually (alongside any other groups).
		/// </summary>
		public int MinGroupSize { get; set; }
        public IEnumerable<ContentItem> FilterChildren(IEnumerable<ContentItem> previousChildren, Query query, GroupFactoryDelegate groupFactory)
        {
            switch (GroupBy)
            {
                case GroupChildrenMode.RecentWithArchive:
                    return ChildrenWithArchive(previousChildren, query, groupFactory);
                case GroupChildrenMode.Pages:
                    return ChildrenByPage(previousChildren, query, groupFactory);
                case GroupChildrenMode.PagesAfterTreshold:
                    return ChildrenUntilTresholdThenPages(previousChildren, query, groupFactory);
                case GroupChildrenMode.PublishedYear:
                    return ChildrenByYear(previousChildren, query, groupFactory);
                case GroupChildrenMode.PublishedYearMonth:
                    return ChildrenByYearMonth(previousChildren, query, groupFactory);
                case GroupChildrenMode.PublishedYearMonthDay:
                    return ChildrenByYearMonthDay(previousChildren, query, groupFactory);
                case GroupChildrenMode.AlphabeticalIndex:
                    return ChildrenByAlphabeticalIndex(previousChildren, query, groupFactory);
                case GroupChildrenMode.Type:
                    return ChildrenByType(previousChildren, query, groupFactory);
                case GroupChildrenMode.ZoneName:
                    return ChildrenByGroup(previousChildren, query, groupFactory);
                default:
                    return previousChildren;
            }
        }
	    private IEnumerable<IGrouping<TKey, T>> GroupByWithMinSize<T, TKey>(IEnumerable<T> enumerable, Func<T, TKey> groupSelector)
	    {
		    var groups = enumerable.GroupBy(groupSelector).ToList();
		    return groups;
	    }
        private IEnumerable<ContentItem> ChildrenByGroup(IEnumerable<ContentItem> previousChildren, Query query, GroupFactoryDelegate childFactory)
        {
            if (AllowDirectQuery)
            {
                var zones = query.Parent.Children.FindZoneNames().ToList();
                return query.Parent.Children.FindPages()
                    .Concat(zones.Where(z => !string.IsNullOrEmpty(z))
                        .Select(z => childFactory(query.Parent, z, "virtual-grouping/" + z, () => query.Parent.Children.FindParts(z))));
            }
            return GroupByWithMinSize(previousChildren, c => c.ZoneName)
                .OrderBy(g => g.Key)
                .SelectMany(g => g.Key == null ? (IEnumerable<ContentItem>)g : new ContentItem[] { childFactory(query.Parent, g.Key, "virtual-grouping/" + g.Key, () => g) });
        }
        private IEnumerable<ContentItem> ChildrenByType(IEnumerable<ContentItem> previousChildren, Query query, GroupFactoryDelegate childFactory)
        {
            if (AllowDirectQuery)
            {
	            var types = query.Parent.Children.Select(query.AsParameters(), "class")
		            .Select(r => (string) r["class"])
		            .Distinct()
		            .OrderBy(t => t);
                return types.Select(t => childFactory(query.Parent, t, "virtual-grouping/" + t, () => query.Parent.Children.Find(query.AsParameters() & Parameter.Equal("class", t))));
            }
            return GroupByWithMinSize(previousChildren, c => c.GetContentType()) // previousChildren.GroupBy(c => c.GetContentType())
                .OrderBy(g => g.Key)
                .Select(g => childFactory(query.Parent, Map.GetOrCreateDefinition(g.Key).Title, "virtual-grouping/" + g.Key.FullName, () => g));
        }
        private IEnumerable<ContentItem> ChildrenByAlphabeticalIndex(IEnumerable<ContentItem> previousChildren, Query query, GroupFactoryDelegate childFactory)
        {
            if (AllowDirectQuery)
            {
                var letters = query.Parent.Children.Select(query.AsParameters(), "Title")
                    .Select(r => (string)r["Title"])
                    .Select(t => t.FirstOrDefault())
                    .Distinct()
                    .OrderBy(l => l);
                return letters.Select(l => childFactory(query.Parent, l.ToString().ToUpper(), "virtual-grouping/" + l, () => query.Parent.Children.Find(query.AsParameters() & Parameter.Like("Title", l + "%"))));
            }
			return GroupByWithMinSize(previousChildren, c => string.IsNullOrEmpty(c.Title) ? '-' : c.Title.ToUpper().FirstOrDefault())
                .Select(g => childFactory(query.Parent, g.Key.ToString(), "virtual-grouping/" + g.Key, () => g));
        }
        private IEnumerable<ContentItem> ChildrenByYearMonthDay(IEnumerable<ContentItem> previousChildren, Query query, GroupFactoryDelegate childFactory)
        {
            if (AllowDirectQuery)
            {
                var dates = query.Parent.Children.Select(query.AsParameters(), "Published")
                    .Select(r => (DateTime?)r["Published"])
                    .Select(p => p.HasValue ? (DateTime?)p.Value.Date : null)
                    .Distinct()
                    .OrderByDescending(d => d);
                return dates.Select(ym => childFactory(query.Parent, ym.HasValue ? ym.Value.ToShortDateString() : "-", "virtual-grouping/" + (ym.HasValue ? ym.Value.ToString("yyyy-MM-dd") : "-"), () => query.Parent.Children.Find(query.AsParameters() & (ym.HasValue ? (Parameter.GreaterOrEqual("Published", ym.Value) & Parameter.LessThan("Published", ym.Value.AddDays(1))) : Parameter.IsNull("Published")))));
            }
			return GroupByWithMinSize(previousChildren, c => c.Published.HasValue ? c.Published.Value.Date.ToShortDateString() : "-")
                .Select(g => childFactory(query.Parent, g.Key, "virtual-grouping/" + g.Key, () => g));
        }
        private IEnumerable<ContentItem> ChildrenByYearMonth(IEnumerable<ContentItem> previousChildren, Query query, GroupFactoryDelegate childFactory)
        {
            if (AllowDirectQuery)
            {
                var yearsMonths = query.Parent.Children.Select(query.AsParameters(), "Published")
                    .Select(r => (DateTime?)r["Published"])
                    .Select(p => p.HasValue ? (DateTime?)new DateTime(p.Value.Year, p.Value.Month, 1) : null)
                    .Distinct()
                    .OrderByDescending(d => d);
                return yearsMonths.Select(ym => childFactory(query.Parent, ToString(ym), "virtual-grouping/" + ToString(ym), () => query.Parent.Children.Find(query.AsParameters() & (ym.HasValue ? (Parameter.GreaterOrEqual("Published", ym.Value) & Parameter.LessThan("Published", ym.Value.AddMonths(1))) : Parameter.IsNull("Published")))));
            }
			return GroupByWithMinSize(previousChildren, c => c.Published.HasValue ? c.Published.Value.Date.ToString("yyyy-MM") : "-")
                .Select(g => childFactory(query.Parent, g.Key, "virtual-grouping/" + g.Key, () => g));
        }
        private static string ToString(DateTime? ym)
        {
            return ym.HasValue ? ym.Value.ToString("yyyy-MM") : "-";
        }
        private IEnumerable<ContentItem> ChildrenByYear(IEnumerable<ContentItem> previousChildren, Query query, GroupFactoryDelegate childFactory)
        {
            if (AllowDirectQuery)
            {
                var years = query.Parent.Children
                    .Select(query.AsParameters(), "Published")
                    .Select(r => (DateTime?)r["Published"])
                    .Select(p => p.HasValue ? p.Value.Year.ToString() : "-")
                    .Distinct()
                    .OrderByDescending(d => d);
                return years.Select(y => childFactory(query.Parent, y, "virtual-grouping/" + y, () => query.Parent.Children.Find(query.AsParameters() & (y != "-" ? (Parameter.GreaterOrEqual("Published", new DateTime(int.Parse(y), 1, 1)) & Parameter.LessThan("Published", new DateTime(int.Parse(y) + 1, 1, 1))) : Parameter.IsNull("Published")))));
            }
			return GroupByWithMinSize(previousChildren, c => c.Published.HasValue ? c.Published.Value.Date.ToString("yyyy") : "-")
                .Select(g => childFactory(query.Parent, g.Key, "virtual-grouping/" + g.Key, () => g));
        }
        private IEnumerable<ContentItem> ChildrenUntilTresholdThenPages(IEnumerable<ContentItem> previousChildren, Query query, GroupFactoryDelegate childFactory)
        {
            if (AllowDirectQuery)
            {
                int dbCount = query.Parent.Children.FindCount(query.AsParameters());
                if (dbCount < StartPagingTreshold)
                    return previousChildren;
            
                var unpaged = query.Parent.Children.Find(query.AsParameters().Take(StartPagingTreshold));
                return unpaged.Concat(
                    Enumerable.Range(0, (dbCount - StartPagingTreshold + PageSize - 1) / PageSize)
                    .Select(i => childFactory(query.Parent, (StartPagingTreshold + i * PageSize + 1) + "-" + (StartPagingTreshold + i * PageSize + PageSize), "virtual-grouping/" + i, () => query.Parent.Children.Find(query.AsParameters().Skip(StartPagingTreshold + i * PageSize).Take(PageSize)))));
            }
            var prevChildren = previousChildren as ContentItem[] ?? previousChildren.ToArray();


Please complete the code given below. 
#!/usr/bin/env python
import socket
import struct
import threading
import time
import dns
from dnsdisttests import DNSDistTest
try:
  range = xrange
except NameError:
  pass
class TestTCPShort(DNSDistTest):
    # this test suite uses a different responder port
    # because, contrary to the other ones, its
    # responders allow trailing data and multiple responses,
    # and we don't want to mix things up.
    _testServerPort = 5361
    _serverKey = 'server.key'
    _serverCert = 'server.chain'
    _serverName = 'tls.tests.dnsdist.org'
    _caCert = 'ca.pem'
    _tlsServerPort = 8453
    _tcpSendTimeout = 60
    _config_template = """
    newServer{address="127.0.0.1:%s"}
    addTLSLocal("127.0.0.1:%s", "%s", "%s")
    setTCPSendTimeout(%d)
    """
    _config_params = ['_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_tcpSendTimeout']
    @classmethod
    def startResponders(cls):
        print("Launching responders..")
        cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, True])
        cls._UDPResponder.setDaemon(True)
        cls._UDPResponder.start()
        cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, True, True])
        cls._TCPResponder.setDaemon(True)
        cls._TCPResponder.start()
    def testTCPShortRead(self):
        """
        TCP: Short read from client
        """
        name = 'short-read.tcp-short.tests.powerdns.com.'
        query = dns.message.make_query(name, 'A', 'IN')
        expectedResponse = dns.message.make_response(query)
        rrset = dns.rrset.from_text(name,
                                    3600,
                                    dns.rdataclass.IN,
                                    dns.rdatatype.A,
                                    '192.0.2.1')
        expectedResponse.answer.append(rrset)
        conn = self.openTCPConnection()
        wire = query.to_wire()
        # announce 7680 bytes (more than 4096, less than 8192 - the 512 bytes dnsdist is going to add)
        announcedSize = 7680
        paddingSize = announcedSize - len(wire)
        wire = wire + (b'A' * (paddingSize - 1))
        self._toResponderQueue.put(expectedResponse, True, 2.0)
        sizeBytes = struct.pack("!H", announcedSize)
        conn.send(sizeBytes[:1])
        time.sleep(1)
        conn.send(sizeBytes[1:])
        # send announcedSize bytes minus 1 so we get a second read
        conn.send(wire)
        time.sleep(1)
        # send the remaining byte
        conn.send(b'A')
        (receivedQuery, receivedResponse) = self.recvTCPResponseOverConnection(conn, True)
        conn.close()
        self.assertTrue(receivedQuery)
        self.assertTrue(receivedResponse)
        receivedQuery.id = query.id
        self.assertEqual(query, receivedQuery)
        self.assertEqual(receivedResponse, expectedResponse)
    def testTCPTLSShortRead(self):
        """
        TCP/TLS: Short read from client
        """
        name = 'short-read-tls.tcp-short.tests.powerdns.com.'
        query = dns.message.make_query(name, 'A', 'IN')
        expectedResponse = dns.message.make_response(query)
        rrset = dns.rrset.from_text(name,
                                    3600,
                                    dns.rdataclass.IN,
                                    dns.rdatatype.A,
                                    '192.0.2.1')
        expectedResponse.answer.append(rrset)
        conn = self.openTLSConnection(self._tlsServerPort, self._serverName, self._caCert)
        wire = query.to_wire()
        # announce 7680 bytes (more than 4096, less than 8192 - the 512 bytes dnsdist is going to add)
        announcedSize = 7680
        paddingSize = announcedSize - len(wire)
        wire = wire + (b'A' * (paddingSize - 1))
        self._toResponderQueue.put(expectedResponse, True, 2.0)
        sizeBytes = struct.pack("!H", announcedSize)
        conn.send(sizeBytes[:1])
        time.sleep(1)
        conn.send(sizeBytes[1:])
        # send announcedSize bytes minus 1 so we get a second read
        conn.send(wire)
        time.sleep(1)
        # send the remaining byte
        conn.send(b'A')
        (receivedQuery, receivedResponse) = self.recvTCPResponseOverConnection(conn, True)
        conn.close()
        self.assertTrue(receivedQuery)
        self.assertTrue(receivedResponse)
        receivedQuery.id = query.id
        self.assertEqual(query, receivedQuery)
        self.assertEqual(receivedResponse, expectedResponse)
    def testTCPShortWrite(self):
        """
        TCP: Short write to client
        """
        name = 'short-write.tcp-short.tests.powerdns.com.'
        query = dns.message.make_query(name, 'AXFR', 'IN')
        # we prepare a large AXFR answer
        # SOA + 200 dns messages of one huge TXT RRset each + SOA
        responses = []
        soa = dns.rrset.from_text(name,
                                  60,
                                  dns.rdataclass.IN,
                                  dns.rdatatype.SOA,
                                  'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
        soaResponse = dns.message.make_response(query)
        soaResponse.use_edns(edns=False)
        soaResponse.answer.append(soa)
        responses.append(soaResponse)
        response = dns.message.make_response(query)
        response.use_edns(edns=False)
        content = ""
        for i in range(200):
            if len(content) > 0:
                content = content + ', '
            content = content + (str(i)*50)
        rrset = dns.rrset.from_text(name,
                                    3600,
                                    dns.rdataclass.IN,
                                    dns.rdatatype.TXT,
                                    content)
        response.answer.append(rrset)
        for _ in range(200):
            responses.append(response)
        responses.append(soaResponse)
        conn = self.openTCPConnection()
        for response in responses:
            self._toResponderQueue.put(response, True, 2.0)
        self.sendTCPQueryOverConnection(conn, query)
        # we sleep for one second, making sure that dnsdist
        # will fill its TCP window and buffers, which will result
        # in some short writes
        time.sleep(1)
        # we then read the messages
        receivedResponses = []
        while True:
            datalen = conn.recv(2)
            if not datalen:
                break
            (datalen,) = struct.unpack("!H", datalen)
            data = b''
            remaining = datalen
            got = conn.recv(remaining)
            while got:
                data = data + got
                if len(data) == datalen:
                    break
                remaining = remaining - len(got)
                if remaining <= 0:
                    break
                got = conn.recv(remaining)
            if data and len(data) == datalen:
                receivedResponse = dns.message.from_wire(data)
                receivedResponses.append(receivedResponse)
        receivedQuery = None
        if not self._fromResponderQueue.empty():
            receivedQuery = self._fromResponderQueue.get(True, 2.0)
        conn.close()
        # and check that everything is good
        self.assertTrue(receivedQuery)
        receivedQuery.id = query.id
        self.assertEqual(query, receivedQuery)
        self.assertEqual(receivedResponses, responses)
    def testTCPTLSShortWrite(self):
        """
        TCP/TLS: Short write to client
        """
        # same as testTCPShortWrite but over TLS this time
        name = 'short-write-tls.tcp-short.tests.powerdns.com.'
        query = dns.message.make_query(name, 'AXFR', 'IN')
        responses = []
        soa = dns.rrset.from_text(name,
                                  60,
                                  dns.rdataclass.IN,
                                  dns.rdatatype.SOA,
                                  'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')


Please complete the code given below. 
/**
 * Copyright (C) 2017 drrb
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.github.drrb.rust.netbeans.parsing;
import com.github.drrb.rust.netbeans.parsing.javacc.RustParserConstants;
import org.netbeans.api.lexer.Language;
import org.netbeans.api.lexer.TokenId;
public enum RustTokenId implements TokenId {
    EOF(RustParserConstants.EOF, TokenCategory.WHITESPACE),
    WHITESPACE(RustParserConstants.WHITESPACE, TokenCategory.WHITESPACE),
    DOC_COMMENT(RustParserConstants.DOC_COMMENT, TokenCategory.COMMENT),
    INNER_DOC_COMMENT(RustParserConstants.INNER_DOC_COMMENT, TokenCategory.COMMENT),
    LINE_COMMENT(RustParserConstants.LINE_COMMENT, TokenCategory.COMMENT),
    BLOCK_COMMENT(RustParserConstants.BLOCK_COMMENT, TokenCategory.COMMENT),
    DOC_BLOCK_COMMENT(RustParserConstants.DOC_BLOCK_COMMENT, TokenCategory.COMMENT),
    INNER_DOC_BLOCK_COMMENT(RustParserConstants.INNER_DOC_BLOCK_COMMENT, TokenCategory.COMMENT),
    NON_NULL(RustParserConstants.NON_NULL, TokenCategory.IDENTIFIER),
    NON_SINGLE_QUOTE(RustParserConstants.NON_SINGLE_QUOTE, TokenCategory.IDENTIFIER),
    NON_DOUBLE_QUOTE(RustParserConstants.NON_DOUBLE_QUOTE, TokenCategory.IDENTIFIER),
    NON_EOL(RustParserConstants.NON_EOL, TokenCategory.IDENTIFIER),
    ASCII(RustParserConstants.ASCII, TokenCategory.IDENTIFIER),
    ASCII_NON_EOL(RustParserConstants.ASCII_NON_EOL, TokenCategory.IDENTIFIER),
    ASCII_NON_SINGLE_QUOTE(RustParserConstants.ASCII_NON_SINGLE_QUOTE, TokenCategory.IDENTIFIER),
    ASCII_NON_DOUBLE_QUOTE(RustParserConstants.ASCII_NON_DOUBLE_QUOTE, TokenCategory.IDENTIFIER),
    STRING_LITERAL(RustParserConstants.STRING_LITERAL, TokenCategory.STRING),
    RAW_STRING_LITERAL(RustParserConstants.RAW_STRING_LITERAL, TokenCategory.STRING),
    CHAR_LITERAL(RustParserConstants.CHAR_LITERAL, TokenCategory.CHARACTER),
    NUMBER_LITERAL(RustParserConstants.NUMBER_LITERAL, TokenCategory.NUMBER),
    BYTE_LITERAL(RustParserConstants.BYTE_LITERAL, TokenCategory.CHARACTER),
    BYTE_STRING_LITERAL(RustParserConstants.BYTE_STRING_LITERAL, TokenCategory.STRING),
    RAW_BYTE_STRING_LITERAL(RustParserConstants.RAW_BYTE_STRING_LITERAL, TokenCategory.STRING),
    STRING_BODY(RustParserConstants.STRING_BODY, TokenCategory.STRING),
    CHAR_BODY(RustParserConstants.CHAR_BODY, TokenCategory.CHARACTER),
    BYTE_BODY(RustParserConstants.BYTE_BODY, TokenCategory.IDENTIFIER),
    COMMON_ESCAPE(RustParserConstants.COMMON_ESCAPE, TokenCategory.IDENTIFIER),
    UNICODE_ESCAPE(RustParserConstants.UNICODE_ESCAPE, TokenCategory.IDENTIFIER),
    FLOAT_SUFFIX(RustParserConstants.FLOAT_SUFFIX, TokenCategory.NUMBER),
    EXPONENT(RustParserConstants.EXPONENT, TokenCategory.NUMBER),
    DEC_LIT(RustParserConstants.DEC_LIT, TokenCategory.NUMBER),
    HEX_DIGIT(RustParserConstants.HEX_DIGIT, TokenCategory.NUMBER),
    OCT_DIGIT(RustParserConstants.OCT_DIGIT, TokenCategory.NUMBER),
    DEC_DIGIT(RustParserConstants.DEC_DIGIT, TokenCategory.NUMBER),
    NONZERO_DEC(RustParserConstants.NONZERO_DEC, TokenCategory.NUMBER),
    RAW_STRING_LITERAL_3(RustParserConstants.RAW_STRING_LITERAL_3, TokenCategory.STRING),
    RAW_STRING_LITERAL_2(RustParserConstants.RAW_STRING_LITERAL_2, TokenCategory.STRING),
    RAW_STRING_LITERAL_1(RustParserConstants.RAW_STRING_LITERAL_1, TokenCategory.STRING),
    RAW_STRING_LITERAL_0(RustParserConstants.RAW_STRING_LITERAL_0, TokenCategory.STRING),
    RAW_BYTE_STRING_LITERAL_3(RustParserConstants.RAW_BYTE_STRING_LITERAL_3, TokenCategory.STRING),
    RAW_BYTE_STRING_LITERAL_2(RustParserConstants.RAW_BYTE_STRING_LITERAL_2, TokenCategory.STRING),
    RAW_BYTE_STRING_LITERAL_1(RustParserConstants.RAW_BYTE_STRING_LITERAL_1, TokenCategory.STRING),
    RAW_BYTE_STRING_LITERAL_0(RustParserConstants.RAW_BYTE_STRING_LITERAL_0, TokenCategory.STRING),
    DOUBLE_COLON(RustParserConstants.DOUBLE_COLON, TokenCategory.SEPARATOR),
    ARROW(RustParserConstants.ARROW, TokenCategory.SEPARATOR),
    DOUBLE_ARROW(RustParserConstants.DOUBLE_ARROW, TokenCategory.OPERATOR),
    HASH(RustParserConstants.HASH, TokenCategory.SEPARATOR),
    LEFT_BRACKET(RustParserConstants.LEFT_BRACKET, TokenCategory.SEPARATOR),
    RIGHT_BRACKET(RustParserConstants.RIGHT_BRACKET, TokenCategory.SEPARATOR),
    LEFT_PAREN(RustParserConstants.LEFT_PAREN, TokenCategory.SEPARATOR),
    RIGHT_PAREN(RustParserConstants.RIGHT_PAREN, TokenCategory.SEPARATOR),
    LEFT_BRACE(RustParserConstants.LEFT_BRACE, TokenCategory.SEPARATOR),
    RIGHT_BRACE(RustParserConstants.RIGHT_BRACE, TokenCategory.SEPARATOR),
    COMMA(RustParserConstants.COMMA, TokenCategory.SEPARATOR),
    COLON(RustParserConstants.COLON, TokenCategory.SEPARATOR),
    PLUS(RustParserConstants.PLUS, TokenCategory.OPERATOR),
    DASH(RustParserConstants.DASH, TokenCategory.OPERATOR),
    STAR(RustParserConstants.STAR, TokenCategory.OPERATOR),
    FORWARD_SLASH(RustParserConstants.FORWARD_SLASH, TokenCategory.OPERATOR),
    PERCENT(RustParserConstants.PERCENT, TokenCategory.OPERATOR),
    AMPERSAND(RustParserConstants.AMPERSAND, TokenCategory.OPERATOR),
    PIPE(RustParserConstants.PIPE, TokenCategory.OPERATOR),
    HAT(RustParserConstants.HAT, TokenCategory.OPERATOR),
    DOUBLE_AMPERSAND(RustParserConstants.DOUBLE_AMPERSAND, TokenCategory.OPERATOR),
    DOUBLE_PIPE(RustParserConstants.DOUBLE_PIPE, TokenCategory.OPERATOR),
    LEFT_ANGLE_BRACKET(RustParserConstants.LEFT_ANGLE_BRACKET, TokenCategory.SEPARATOR),
    RIGHT_ANGLE_BRACKET(RustParserConstants.RIGHT_ANGLE_BRACKET, TokenCategory.SEPARATOR),
    SHIFT_LEFT(RustParserConstants.SHIFT_LEFT, TokenCategory.OPERATOR),
    SHIFT_RIGHT(RustParserConstants.SHIFT_RIGHT, TokenCategory.OPERATOR),
    LESS_THAN_EQUAL(RustParserConstants.LESS_THAN_EQUAL, TokenCategory.OPERATOR),
    GREATER_THAN_EQUAL(RustParserConstants.GREATER_THAN_EQUAL, TokenCategory.OPERATOR),
    SEMICOLON(RustParserConstants.SEMICOLON, TokenCategory.SEPARATOR),
    DOUBLE_EQUALS(RustParserConstants.DOUBLE_EQUALS, TokenCategory.OPERATOR),
    NOT_EQUAL(RustParserConstants.NOT_EQUAL, TokenCategory.OPERATOR),
    PLUS_EQUALS(RustParserConstants.PLUS_EQUALS, TokenCategory.OPERATOR),
    MINUS_EQUALS(RustParserConstants.MINUS_EQUALS, TokenCategory.OPERATOR),
    TIMES_EQUALS(RustParserConstants.TIMES_EQUALS, TokenCategory.OPERATOR),
    DIVIDE_EQUALS(RustParserConstants.DIVIDE_EQUALS, TokenCategory.OPERATOR),
    MOD_EQUALS(RustParserConstants.MOD_EQUALS, TokenCategory.OPERATOR),
    AND_EQUALS(RustParserConstants.AND_EQUALS, TokenCategory.OPERATOR),
    OR_EQUALS(RustParserConstants.OR_EQUALS, TokenCategory.OPERATOR),
    XOR_EQUALS(RustParserConstants.XOR_EQUALS, TokenCategory.OPERATOR),
    SHIFT_LEFT_EQUALS(RustParserConstants.SHIFT_LEFT_EQUALS, TokenCategory.OPERATOR),
    SHIFT_RIGHT_EQUALS(RustParserConstants.SHIFT_RIGHT_EQUALS, TokenCategory.OPERATOR),
    BANG(RustParserConstants.BANG, TokenCategory.OPERATOR),
    EQUALS(RustParserConstants.EQUALS, TokenCategory.OPERATOR),
    DOT(RustParserConstants.DOT, TokenCategory.SEPARATOR),
    DOUBLE_DOT(RustParserConstants.DOUBLE_DOT, TokenCategory.IDENTIFIER),
    DOLLAR(RustParserConstants.DOLLAR, TokenCategory.SEPARATOR),
    HASH_ROCKET(RustParserConstants.HASH_ROCKET, TokenCategory.SEPARATOR),
    ABSTRACT(RustParserConstants.ABSTRACT, TokenCategory.IDENTIFIER),
    ALIGNOF(RustParserConstants.ALIGNOF, TokenCategory.IDENTIFIER),
    AS(RustParserConstants.AS, TokenCategory.KEYWORD),
    BECOME(RustParserConstants.BECOME, TokenCategory.IDENTIFIER),
    BOX(RustParserConstants.BOX, TokenCategory.IDENTIFIER),
    BREAK(RustParserConstants.BREAK, TokenCategory.KEYWORD),
    CONST(RustParserConstants.CONST, TokenCategory.KEYWORD),
    CONTINUE(RustParserConstants.CONTINUE, TokenCategory.KEYWORD),
    CRATE(RustParserConstants.CRATE, TokenCategory.KEYWORD),
    DO(RustParserConstants.DO, TokenCategory.KEYWORD),
    ELSE(RustParserConstants.ELSE, TokenCategory.KEYWORD),
    ENUM(RustParserConstants.ENUM, TokenCategory.KEYWORD),
    EXTERN(RustParserConstants.EXTERN, TokenCategory.KEYWORD),
    FALSE(RustParserConstants.FALSE, TokenCategory.KEYWORD),
    FINAL(RustParserConstants.FINAL, TokenCategory.KEYWORD),
    FN(RustParserConstants.FN, TokenCategory.KEYWORD),
    FOR(RustParserConstants.FOR, TokenCategory.KEYWORD),
    IF(RustParserConstants.IF, TokenCategory.KEYWORD),
    IMPL(RustParserConstants.IMPL, TokenCategory.KEYWORD),
    IN(RustParserConstants.IN, TokenCategory.KEYWORD),
    LET(RustParserConstants.LET, TokenCategory.KEYWORD),
    LOOP(RustParserConstants.LOOP, TokenCategory.KEYWORD),
    MACRO(RustParserConstants.MACRO, TokenCategory.KEYWORD),
    MACRO_RULES(RustParserConstants.MACRO_RULES, TokenCategory.IDENTIFIER),
    MATCH(RustParserConstants.MATCH, TokenCategory.KEYWORD),
    MOD(RustParserConstants.MOD, TokenCategory.IDENTIFIER),
    MOVE(RustParserConstants.MOVE, TokenCategory.IDENTIFIER),
    MUT(RustParserConstants.MUT, TokenCategory.KEYWORD),
    OFFSETOF(RustParserConstants.OFFSETOF, TokenCategory.IDENTIFIER),
    OVERRIDE(RustParserConstants.OVERRIDE, TokenCategory.IDENTIFIER),
    PRIV(RustParserConstants.PRIV, TokenCategory.KEYWORD),
    PROC(RustParserConstants.PROC, TokenCategory.IDENTIFIER),
    PUB(RustParserConstants.PUB, TokenCategory.KEYWORD),
    PURE(RustParserConstants.PURE, TokenCategory.IDENTIFIER),
    REF(RustParserConstants.REF, TokenCategory.IDENTIFIER),
    RETURN(RustParserConstants.RETURN, TokenCategory.KEYWORD),
    BIG_SELF(RustParserConstants.BIG_SELF, TokenCategory.IDENTIFIER),
    SELF(RustParserConstants.SELF, TokenCategory.KEYWORD),
    SIZEOF(RustParserConstants.SIZEOF, TokenCategory.KEYWORD),
    STATIC(RustParserConstants.STATIC, TokenCategory.KEYWORD),
    STRUCT(RustParserConstants.STRUCT, TokenCategory.KEYWORD),
    SUPER(RustParserConstants.SUPER, TokenCategory.IDENTIFIER),
    TRAIT(RustParserConstants.TRAIT, TokenCategory.KEYWORD),
    TRUE(RustParserConstants.TRUE, TokenCategory.KEYWORD),
    TYPE(RustParserConstants.TYPE, TokenCategory.KEYWORD),
    TYPEOF(RustParserConstants.TYPEOF, TokenCategory.KEYWORD),
    UNSAFE(RustParserConstants.UNSAFE, TokenCategory.KEYWORD),
    UNSIZED(RustParserConstants.UNSIZED, TokenCategory.KEYWORD),
    USE(RustParserConstants.USE, TokenCategory.KEYWORD),
    VIRTUAL(RustParserConstants.VIRTUAL, TokenCategory.KEYWORD),
    WHERE(RustParserConstants.WHERE, TokenCategory.KEYWORD),
    WHILE(RustParserConstants.WHILE, TokenCategory.KEYWORD),
    YIELD(RustParserConstants.YIELD, TokenCategory.KEYWORD),
    IDENTIFIER(RustParserConstants.IDENTIFIER, TokenCategory.IDENTIFIER),
    LABEL(RustParserConstants.LABEL, TokenCategory.IDENTIFIER),
    XID_start(RustParserConstants.XID_start, TokenCategory.IDENTIFIER),
    XID_continue(RustParserConstants.XID_continue, TokenCategory.IDENTIFIER),
    GARBAGE(RustParserConstants.GARBAGE, TokenCategory.IDENTIFIER);
    public static final RustLanguageHierarchy LANGUAGE_HIERARCHY = new RustLanguageHierarchy();
    private static final RustTokenId[] LOOKUP;
    static {
        int highestValue = 0;
        for (RustTokenId kind : values()) {
            highestValue = highestValue > kind.javaccKind ? highestValue : kind.javaccKind;
        }
        LOOKUP = new RustTokenId[highestValue + 1];
        for (RustTokenId kind : values()) {
            LOOKUP[kind.javaccKind] = kind;
        }
    }
    public static Language<RustTokenId> language() {
        return LANGUAGE_HIERARCHY.language();
    }
    private final int javaccKind;
    private final TokenCategory category;
    RustTokenId(int javaccKind, TokenCategory category) {
        this.javaccKind = javaccKind;
        this.category = category;
    }
    public static RustTokenId get(int javaccKind) {
        RustTokenId kind = LOOKUP[javaccKind];


Please complete the code given below. 
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SenseNet.ContentRepository.Storage;
using SenseNet.ContentRepository.Fields;
namespace SenseNet.Portal.UI.Controls
{
	[ToolboxData("<{0}:WholeNumber ID=\"WholeNumber1\" runat=server></{0}:WholeNumber>")]
	public class WholeNumber : FieldControl, INamingContainer, ITemplateFieldControl
	{
        protected string PercentageControlID = "LabelForPercentage";
        // Fields ///////////////////////////////////////////////////////////////////////
		private TextBox _inputTextBox;
        // Constructor //////////////////////////////////////////////////////////////////
		public WholeNumber()
		{
            InnerControlID = "InnerWholeNumber";
			_inputTextBox = new TextBox { ID = InnerControlID };
		}
        // Methods //////////////////////////////////////////////////////////////////////
        public override void SetData(object data)
        {
            if (data == null)
            {
                _inputTextBox.Text = string.Empty;
            }
            else
            {
                _inputTextBox.Text = Convert.ToInt32(data) == int.MinValue ? string.Empty : data.ToString();
            }
            #region template
            if ((!UseBrowseTemplate && !UseEditTemplate) && !UseInlineEditTemplate)
                return;
            SetTitleAndDescription();
            var innerControl = GetInnerControl() as TextBox;
            var perc = GetLabelForPercentageControl();
            
            if (innerControl != null)
                innerControl.Text = Convert.ToString(_inputTextBox.Text);
            if (perc != null)
            {
                perc.Text = GetPercentageSign();
                perc.Visible = !string.IsNullOrEmpty(perc.Text);
            }
            #endregion
        }
        public override object GetData()
		{
            var innerControl = GetInnerControl() as TextBox;
            if ((!UseBrowseTemplate && !UseEditTemplate && !UseInlineEditTemplate) || innerControl == null)
            {
                #region original
                if (_inputTextBox.Text.Length == 0)
                    return null;
                return Convert.ToInt32(_inputTextBox.Text);
                #endregion
            }
            if (innerControl.Text.Length == 0) 
                return null;
            
            return Convert.ToInt32(innerControl.Text);
		}
        // Events ///////////////////////////////////////////////////////////////////////
		protected override void OnInit(EventArgs e)
		{
            base.OnInit(e);
		    #region template
		    if (UseBrowseTemplate || UseEditTemplate || UseInlineEditTemplate)
		        return;
		    #endregion
		    #region original flow
		    _inputTextBox.CssClass = String.IsNullOrEmpty(this.CssClass) ? "sn-ctrl sn-ctrl-number" : this.CssClass;
		    Controls.Add(_inputTextBox);
		    //_inputTextBox.ID = String.Concat(this.ID, "_", this.ContentHandler.Id.ToString());
		    #endregion
		}
		protected override void RenderContents(HtmlTextWriter writer)
		{
            #region template
            if (UseBrowseTemplate)
            {
                base.RenderContents(writer);
                return;
            }
            if (UseEditTemplate)
            {
                ManipulateTemplateControls();
                base.RenderContents(writer);
                return;
            }
            if (UseInlineEditTemplate)
            {
                ManipulateTemplateControls();
                base.RenderContents(writer);
                return;
            }
            #endregion
			if (this.RenderMode == FieldControlRenderMode.Browse)
				RenderSimple(writer);
			else
				RenderEditor(writer);
		}
		private void RenderSimple(HtmlTextWriter writer)
		{
			writer.Write(_inputTextBox.Text);
            RenderPercentage(writer);
		}
		private void RenderEditor(HtmlTextWriter writer)
		{
			if (this.RenderMode == FieldControlRenderMode.InlineEdit)
            {
                var titleText = String.Concat(this.Field.DisplayName, " ", this.Field.Description);
                _inputTextBox.Attributes.Add("Title", titleText);
            }
			if (this.Field.ReadOnly)
			{
				writer.Write(_inputTextBox.Text);
			}
			else if (this.ReadOnly)
			{
				_inputTextBox.Enabled = !this.ReadOnly;
				_inputTextBox.EnableViewState = false;
				_inputTextBox.RenderControl(writer);
			}
			else
			{
				// render read/write control
				_inputTextBox.RenderControl(writer);
			}
		    RenderPercentage(writer);
		}
        private void ManipulateTemplateControls()
        {
            //
            //  This method is needed to ensure the common fieldcontrol logic.
            //
            var innerWholeNumber = GetInnerControl() as TextBox;
            var lt = GetLabelForTitleControl() as Label;
            var ld = GetLabelForDescription() as Label;
            if (innerWholeNumber == null) return;
            if (Field.ReadOnly)
            {
                var p = innerWholeNumber.Parent;
                if (p != null)
                {
                    p.Controls.Remove(innerWholeNumber);
                    if (lt != null) lt.AssociatedControlID = string.Empty;
                    if (ld != null) ld.AssociatedControlID = string.Empty;
                    p.Controls.Add(new LiteralControl(innerWholeNumber.Text));
                }
            }
            else if (ReadOnly)
            {
                innerWholeNumber.Enabled = !ReadOnly;
                innerWholeNumber.EnableViewState = false;
            }
            if (RenderMode != FieldControlRenderMode.InlineEdit)
                return;
            innerWholeNumber.Attributes.Add("Title", String.Concat(Field.DisplayName, " ", Field.Description));
   
        }
        private void RenderPercentage(HtmlTextWriter writer)
        {
            writer.Write(GetPercentageSign());
        }
        private string GetPercentageSign()
        {
            var fs = this.Field.FieldSetting as IntegerFieldSetting;
            if (fs == null)
                return string.Empty;
            if (fs.ShowAsPercentage.HasValue && fs.ShowAsPercentage.Value)
                return "%";
            return string.Empty;
        }
        #region ITemplateFieldControl Members
        public Control GetInnerControl()
        {
            return this.FindControlRecursive(InnerControlID) as TextBox;
        }
        public Control GetLabelForDescription()
        {


Please complete the code given below. 
# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import xml.sax
import urllib, base64
import time
import boto.utils
import types
from boto.connection import AWSAuthConnection
from boto import handler
from boto.s3.bucket import Bucket
from boto.s3.key import Key
from boto.resultset import ResultSet
from boto.exception import S3ResponseError, S3CreateError, BotoClientError
def assert_case_insensitive(f):
    def wrapper(*args, **kwargs):
        if len(args) == 3 and not (args[2].islower() or args[2].isalnum()):
            raise BotoClientError("Bucket names cannot contain upper-case " \
            "characters when using either the sub-domain or virtual " \
        "hosting calling format.")
        return f(*args, **kwargs)
    return wrapper
class _CallingFormat:
    def build_url_base(self, protocol, server, bucket, key=''):
        url_base = '%s://' % protocol
        url_base += self.build_host(server, bucket)
        url_base += self.build_path_base(bucket, key)
        return url_base
    def build_host(self, server, bucket):
        if bucket == '':
            return server
        else:
            return self.get_bucket_server(server, bucket)
    def build_auth_path(self, bucket, key=''):
        path = ''
        if bucket != '':
            path = '/' + bucket
        return path + '/%s' % urllib.quote(key)
    def build_path_base(self, bucket, key=''):
        return '/%s' % urllib.quote(key)
class SubdomainCallingFormat(_CallingFormat):
    @assert_case_insensitive
    def get_bucket_server(self, server, bucket):
        return '%s.%s' % (bucket, server)
class VHostCallingFormat(_CallingFormat):
    @assert_case_insensitive
    def get_bucket_server(self, server, bucket):
        return bucket
class OrdinaryCallingFormat(_CallingFormat):
    def get_bucket_server(self, server, bucket):
        return server
    def build_path_base(self, bucket, key=''):
        path_base = '/'
        if bucket:
            path_base += "%s/" % bucket
        return path_base + urllib.quote(key)
class Location:
    DEFAULT = ''
    EU = 'EU'
class S3Connection(AWSAuthConnection):
    DefaultHost = 's3.amazonaws.com'
    QueryString = 'Signature=%s&Expires=%d&AWSAccessKeyId=%s'
    def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
                 is_secure=True, port=None, proxy=None, proxy_port=None,
                 proxy_user=None, proxy_pass=None,
                 host=DefaultHost, debug=0, https_connection_factory=None,
                 calling_format=SubdomainCallingFormat(), path='/'):
        self.calling_format = calling_format
        AWSAuthConnection.__init__(self, host,
                aws_access_key_id, aws_secret_access_key,
                is_secure, port, proxy, proxy_port, proxy_user, proxy_pass,
                debug=debug, https_connection_factory=https_connection_factory,
                path=path)
    def __iter__(self):
        return self.get_all_buckets()
    def __contains__(self, bucket_name):
       return not (self.lookup(bucket_name) is None)
    def build_post_policy(self, expiration_time, conditions):
        """
        Taken from the AWS book Python examples and modified for use with boto
        """
        if type(expiration_time) != time.struct_time:
            raise 'Policy document must include a valid expiration Time object'
        # Convert conditions object mappings to condition statements
        return '{"expiration": "%s",\n"conditions": [%s]}' % \
            (time.strftime(boto.utils.ISO8601, expiration_time), ",".join(conditions))
    def build_post_form_args(self, bucket_name, key, expires_in = 6000,
                        acl = None, success_action_redirect = None, max_content_length = None,
                        http_method = "http"):
        """
        Taken from the AWS book Python examples and modified for use with boto
        This only returns the arguments required for the post form, not the actual form
        This does not return the file input field which also needs to be added
        @param bucket_name: Bucket to submit to
        @param key: Key name, optionally add ${filename} to the end to attach the submitted filename
        @param expires_in: Time (in seconds) before this expires, defaults to 6000
        @param acl: ACL rule to use, if any
        @param success_action_redirect: URL to redirect to on success
        @param max_content_length: Maximum size for this file
        @param http_method: HTTP Method to use, "http" or "https"
        @return: {"action": action_url_to_post_to, "fields": [ {"name": field_name, "value":  field_value}, {"name": field_name2, "value": field_value2} ] }
        @rtype: dict
        """
        fields = []
        conditions = []
        expiration = time.gmtime(int(time.time() + expires_in))
        # Generate policy document
        conditions.append('{"bucket": "%s"}' % bucket_name)
        if key.endswith("${filename}"):
            conditions.append('["starts-with", "$key", "%s"]' % key[:-len("${filename}")])
        else:
            conditions.append('{"key": "%s"}' % key)
        if acl:
            conditions.append('{"acl": "%s"}' % acl)
            fields.append({ "name": "acl", "value": acl})
        if success_action_redirect:
            conditions.append('{"success_action_redirect": "%s"}' % success_action_redirect)
            fields.append({ "name": "success_action_redirect", "value": success_action_redirect})
        if max_content_length:
            conditions.append('["content-length-range", 0, %i]' % max_content_length)
            fields.append({"name":'content-length-range', "value": "0,%i" % max_content_length})
        policy = self.build_post_policy(expiration, conditions)
        # Add the base64-encoded policy document as the 'policy' field
        policy_b64 = base64.b64encode(policy)
        fields.append({"name": "policy", "value": policy_b64})
        # Add the AWS access key as the 'AWSAccessKeyId' field
        fields.append({"name": "AWSAccessKeyId", "value": self.aws_access_key_id})
        # Add signature for encoded policy document as the 'AWSAccessKeyId' field
        hmac_copy = self.hmac.copy()
        hmac_copy.update(policy_b64)
        signature = base64.encodestring(hmac_copy.digest()).strip()
        fields.append({"name": "signature", "value": signature})
        fields.append({"name": "key", "value": key})
        # HTTPS protocol will be used if the secure HTTP option is enabled.
        url = '%s://%s.s3.amazonaws.com/' % (http_method, bucket_name)
        return {"action": url, "fields": fields}
    def generate_url(self, expires_in, method, bucket='', key='',
                     headers=None, query_auth=True, force_http=False):
        if not headers:
            headers = {}
        expires = int(time.time() + expires_in)
        auth_path = self.calling_format.build_auth_path(bucket, key)
        canonical_str = boto.utils.canonical_string(method, auth_path,
                                                    headers, expires)
        hmac_copy = self.hmac.copy()
        hmac_copy.update(canonical_str)
        b64_hmac = base64.encodestring(hmac_copy.digest()).strip()
        encoded_canonical = urllib.quote_plus(b64_hmac)
        path = self.calling_format.build_path_base(bucket, key)
        if query_auth:
            query_part = '?' + self.QueryString % (encoded_canonical, expires,
                                             self.aws_access_key_id)
        else:
            query_part = ''
        if force_http:
            protocol = 'http'
        else:
            protocol = self.protocol
        return self.calling_format.build_url_base(protocol, self.server_name(),
                                                  bucket, key) + query_part
    def get_all_buckets(self):
        response = self.make_request('GET')
        body = response.read()
        if response.status > 300:
            raise S3ResponseError(response.status, response.reason, body)
        rs = ResultSet([('Bucket', Bucket)])
        h = handler.XmlHandler(rs, self)
        xml.sax.parseString(body, h)
        return rs
    def get_canonical_user_id(self):
        """
        Convenience method that returns the "CanonicalUserID" of the user who's credentials
        are associated with the connection.  The only way to get this value is to do a GET
        request on the service which returns all buckets associated with the account.  As part
        of that response, the canonical userid is returned.  This method simply does all of
        that and then returns just the user id.
        @rtype: string
        @return: A string containing the canonical user id.
        """
        rs = self.get_all_buckets()
        return rs.ID
    def get_bucket(self, bucket_name, validate=True):
        bucket = Bucket(self, bucket_name)
        if validate:
            rs = bucket.get_all_keys(None, maxkeys=0)
        return bucket
    def lookup(self, bucket_name, validate=True):
        try:
            bucket = self.get_bucket(bucket_name, validate)
        except:
            bucket = None
        return bucket
    def create_bucket(self, bucket_name, headers=None, location=Location.DEFAULT, policy=None):
        """
        Creates a new located bucket. By default it's in the USA. You can pass
        Location.EU to create an European bucket.
        @type bucket_name: string
        @param bucket_name: The name of the new bucket
        
        @type headers: dict
        @param headers: Additional headers to pass along with the request to AWS.
        @type location: L{Location<boto.s3.connection.Location>}
        @param location: The location of the new bucket
        
        @type policy: L{CannedACLString<boto.s3.acl.CannedACLStrings>}
        @param policy: A canned ACL policy that will be applied to the new key in S3.
             
        """
        if policy:
            if headers:
                headers['x-amz-acl'] = policy
            else:
                headers = {'x-amz-acl' : policy}
        if location == Location.DEFAULT:
            data = ''
        else:
            data = '<CreateBucketConstraint><LocationConstraint>' + \
                    location + '</LocationConstraint></CreateBucketConstraint>'
        response = self.make_request('PUT', bucket_name, headers=headers,
                data=data)
        body = response.read()
        if response.status == 409:
            raise S3CreateError(response.status, response.reason, body)
        if response.status == 200:
            return Bucket(self, bucket_name)
        else:
            raise S3ResponseError(response.status, response.reason, body)
    def delete_bucket(self, bucket):
        response = self.make_request('DELETE', bucket)
        body = response.read()
        if response.status != 204:
            raise S3ResponseError(response.status, response.reason, body)
    def make_request(self, method, bucket='', key='', headers=None, data='',
            query_args=None, sender=None):
        if isinstance(bucket, Bucket):
            bucket = bucket.name
        if isinstance(key, Key):
            key = key.name
        path = self.calling_format.build_path_base(bucket, key)
        auth_path = self.calling_format.build_auth_path(bucket, key)
        host = self.calling_format.build_host(self.server_name(), bucket)
        if query_args:


Please complete the code given below. 
package de.uvwxy.footpath.gui;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Environment;
import android.util.Log;
import de.uvwxy.footpath.R;
import de.uvwxy.footpath.ToolBox;
import de.uvwxy.footpath.core.Positioner;
import de.uvwxy.footpath.graph.GraphEdge;
import de.uvwxy.footpath.graph.LatLonPos;
import de.uvwxy.paintbox.PaintBox;
/**
 * 
 * @author Paul Smith
 * 
 */
class PaintBoxMap extends PaintBox {
	private static final String MAP_SETTINGS = "PaintBoxMap";
	
	private Tile[] tiles;								// array to store osm tiles
	private Bitmap arrow;								// png, this is the user position
	private Bitmap arrowred;							// user position in red
	private Bitmap stairs;								// icon to show stairs on map
	
	private Context context;							
	private Navigator navigator;						// object to get data from (location, bearing,..)
	private LinkedList<GraphEdge> edges;				// all edges on the path, in right order
	private LatLonPos lbBound;							// left bottom position of bounding box (lat/lon)
	private LatLonPos rtBound;							// rigt top position of bounding box (lat/lon)
	private float gScale = 1.0f;						// global scaling, pressing the zoom buttons will change this
	private float scaleFactor = 0.6f;					// value added/removed when changing zoom level
	
	private boolean runOnce = true;						// needed to create/load resources once
	
	public PaintBoxMap(Context context, Navigator navigator) {
		super(context);
		this.context = context;
		this.navigator = navigator;
		// Load saved zoom level
		this.gScale = context.getSharedPreferences(MAP_SETTINGS,0).getFloat("gScale",1.0f); 
	}
	// create lbBound and rtBound
	private void setBoundaries() {
		double latMin = Double.POSITIVE_INFINITY;
		double latMax = Double.NEGATIVE_INFINITY;
		double lonMin = Double.POSITIVE_INFINITY;
		double lonMax = Double.NEGATIVE_INFINITY;
		for(GraphEdge edge : edges){			// edges contain only edges from path
												// but still, almost every node is searched twice ([a,b][b,c][c,d]...)
			double n0lat = edge.getNode0().getLat();
			double n1lat = edge.getNode1().getLat();
			double n0lon = edge.getNode0().getLon();
			double n1lon = edge.getNode1().getLon();
			
			if(n0lat < latMin)			// find minimum lat
				latMin = n0lat;
			if(n1lat < latMin)
				latMin = n1lat;
			if(n0lon < lonMin)			// find minimum lon
				lonMin = n0lon;
			if(n1lon < lonMin)
				lonMin = n1lon;
			
			if(n0lat > latMax)			// find maximum lat
				latMax = n0lat;
			if(n1lat > latMax)
				latMax = n1lat;
			if(n0lon > lonMax)			// find maximum lon
				lonMax = n0lon;
			if(n1lon > lonMax)
				lonMax = n1lon;
		}
		
		lbBound = new LatLonPos(latMin, lonMin, -1337);
		rtBound = new LatLonPos(latMax, lonMax, -1337);
	}
	
	// load tiles for given zoom level, from sdcard or http
	private Tile[] loadTiles(int zoomlevel, LatLonPos lbBoundary, LatLonPos rtBoundary){
		// source: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
		
		// find out which tiles to get
		int x0 = getTileX(lbBoundary.getLon(), zoomlevel);			// point 0 left top
		int y0 = getTileY(rtBoundary.getLat(), zoomlevel);
		int x1 = getTileX(rtBoundary.getLon(), zoomlevel);			// point 1 right top
		int y2 = getTileY(lbBoundary.getLat(), zoomlevel);			// point 2 left bottom
		
		int diffX = x1 - x0;
		int diffY = y2 - y0;
		
		int arraySize = (diffX+3)*(diffY+3);
		arraySize = arraySize <= 0 ? 1 : arraySize;			// fix size if only one tile needed
		Tile[] res = new Tile[arraySize];
		
		// check if dir exists
		File dir = new File(Environment.getExternalStorageDirectory(),"footpath/");
		if(!dir.exists()){
			dir.mkdir();
		}
		int counter = 0;
		boolean downloadFailed = false;
		for(int x = -1; x <= diffX+1; x++){			// x/y =  -1 to have some more tiles around the building 
			for(int y = -1; y <= diffY+1; y++){   	// because some parts of the building might be overlapping
													// and thus not visible (nicer graphics)
				File f = new File(Environment.getExternalStorageDirectory(),"footpath/tile." 
						+ zoomlevel + "." + (x0+x) + "." + (y0+y) + ".png");
				if(f.exists()){
					// file existed -> read it
					res[counter] = new Tile(zoomlevel, x0+x, y0+y, BitmapFactory.decodeFile(f.getPath()));
					Log.i("FOOTPATH", "Loading from sd footpath/tile."  + zoomlevel + "." + (x0+x) + "." + (y0+y) + ".png)");
				} else {
					// file did not exist -> download it
					URL u = null;
					try {
						u= new URL("http://tile.openstreetmap.org/" + zoomlevel + "/" + (x0+x) + "/" + (y0+y) + ".png");
					} catch (MalformedURLException e) {
						Log.i("FOOTPATH", "URL creation failed (http://tile.openstreetmap.org/"  + zoomlevel + "/" + (x0+x) + "/" + (y0+y) + ".png)" + "\n" + e);
					}    
					try {
						HttpURLConnection c = (HttpURLConnection)u.openConnection();
						c.setDoInput(true);
						InputStream is = c.getInputStream();    
						res[counter] =  new Tile(zoomlevel, x0+x, y0+y, BitmapFactory.decodeStream(is));
						Log.i("FOOTPATH", "Download succeeded (" + u.toString() + ")");
						// -> and save it
						try {
						       FileOutputStream out = new FileOutputStream(f);
						       res[counter].getBitmap().compress(Bitmap.CompressFormat.PNG, 90, out);
						       Log.i("FOOTPATH", "Writing of file suceeded (" + f.toString() + ")");
						} catch (Exception e) {
						      Log.i("FOOTPATH", "Writing of file failed (" + f.toString() + ")" + "\n" + e);
						}
					} catch (IOException e) {
						Log.i("FOOTPATH", "Download failed (" + u.toString() + ")" + "\n" + e);
						downloadFailed = true;
					}
				}
				counter++;
			}
		}
		if(downloadFailed){
			// TODO: Give feedback on failed download of map tiles
		}
		return res;
	}
	
	private int getTileX(double lon, int zoom) {
		return (int)Math.floor( (lon + 180) / 360 * (1<<zoom));
	}
	private int getTileY(double lat, int zoom) {
		return (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		if(runOnce){
			edges = this.navigator.getNavPathEdges();
			setBoundaries();
			tiles = loadTiles(18,lbBound, rtBound);
			arrow = BitmapFactory.decodeResource(getResources(), R.drawable.arrow);
			arrowred = BitmapFactory.decodeResource(getResources(), R.drawable.arrowred);
			stairs = BitmapFactory.decodeResource(getResources(), R.drawable.stairs);
			runOnce = false; 
		}		
		double localScale = gScale;
		LatLonPos pos = navigator.getPosition();			// get position
		
		globalOffsetX = getWidth()/2.0f - getPosX(pos, localScale);		// center position to screen center
		globalOffsetY = getHeight()/2.0f - getPosY(pos, localScale);	// center position to screen center
		
		canvas.drawColor(Color.BLACK); 						// black background
		drawTiles(canvas, localScale);									// draw map
		this.drawPath(canvas, localScale);								// draw route
		// draw arrow.png to the screen (user position indicator)
				
		if(Positioner.isInRange(navigator.getCompassValue(), navigator.getNavPathDir(), navigator.getAcceptanceWidth())){
			Matrix m = new Matrix();
			m = new Matrix();
			m.setRotate((float) (navigator.getCompassValue()),arrow.getWidth()/2.0f,arrow.getHeight()/2.0f);
			m.postTranslate(globalOffsetX + getPosX(pos, localScale) - arrow.getWidth()/2.0f , globalOffsetY + getPosY(pos, localScale) - arrow.getHeight()/2.0f);
			canvas.drawBitmap(arrow,m,null);					// draw arrow.png to the screen (user position indicator)
		}else {
			Matrix m = new Matrix();
			m.setRotate((float) (navigator.getNavPathDir()),arrow.getWidth()/2.0f,arrow.getHeight()/2.0f);
			m.postTranslate(globalOffsetX + getPosX(pos, localScale) - arrow.getWidth()/2.0f , globalOffsetY + getPosY(pos, localScale) - arrow.getHeight()/2.0f);
			canvas.drawBitmap(arrow,m,null);	
			m = new Matrix();
			m.setRotate((float) (navigator.getCompassValue()),arrow.getWidth()/2.0f,arrow.getHeight()/2.0f);
			m.postTranslate(globalOffsetX + getPosX(pos, localScale) - arrow.getWidth()/2.0f , globalOffsetY + getPosY(pos, localScale) - arrow.getHeight()/2.0f);
			canvas.drawBitmap(arrowred,m,null);					// draw arrowred.png to the screen, meaning wrong direction
		}
		
		
		// draw additional text + background (readability)
		canvas.drawRect(0, 0, getWidth(), 148, ToolBox.myPaint(1, Color.BLACK, 128));
		// check if route end reached
		if (navigator.getNavPathEdgeLenLeft() != -1) {
			// draw information
			canvas.drawText(
					"Distance: " + ToolBox.tdp(navigator.getNavPathLen() - navigator.getNavPathLenLeft()) + "m of " +
					ToolBox.tdp(navigator.getNavPathLen()) + "m" , 10, 42, ToolBox.greenPaint(32.0f));
			
			String nextPath = "";
			switch(navigator.getNextTurn()){
			case -1:
				nextPath = "turn left";
				break;
			case 0:
				nextPath = "straight on";
				break;
			case 1:
				nextPath = "turn right";
				break;
			}
			canvas.drawText(
					"Go " + ToolBox.tdp(navigator.getNavPathEdgeLenLeft())
					+ "m then " + nextPath, 10, 74, ToolBox.greenPaint(32.0f));
			Paint p = ToolBox.greenPaint(32.0f);
			if(!Positioner.isInRange(navigator.getNavPathDir(),
					navigator.getCompassValue(),
					navigator.getAcceptanceWidth())){
				p = ToolBox.redPaint(32.0f);
			}
			canvas.drawText(
					"Bearing: " + ToolBox.tdp(navigator.getCompassValue()) + "/" + (ToolBox.tdp(navigator.getNavPathDir())), 10, 106, p);
//			canvas.drawText(
//					"Variances: " + ToolBox.tdp(navigator.getVarianceOfX()) + "/" + ToolBox.tdp(navigator.getVarianceOfY()) 
//					+ "/" + ToolBox.tdp(navigator.getVarianceOfZ()), 10, 138, ToolBox.greenPaint(32.0f));
			canvas.drawText("Est. step length: " 
					+ ToolBox.tdp(navigator.getEstimatedStepLength()) + " vs " + ToolBox.tdp(navigator.getStepLengthInMeters()) ,10, 138, ToolBox.greenPaint(32.0f));
		} else {
			canvas.drawText("Destination ( " + navigator.getRouteEnd().getName() + ") reached", 10, 32, ToolBox.redPaint(32.0f));
		}
	}
	private void drawTiles(Canvas canvas, double localScale){
		for(int i = 0; i < tiles.length; i++){
			if(tiles[i]!=null){
				LatLonPos lt = tiles[i].getLatLonPosLeftTop();
				LatLonPos rb = tiles[i].getLatLonPosRightBottom();
				float left = globalOffsetX + getPosX(lt, localScale);
				float top = globalOffsetY + getPosY(lt, localScale);
				float right = globalOffsetX + getPosX(rb, localScale);
				float bottom = globalOffsetY + getPosY(rb, localScale);


Please complete the code given below. 
using System;
using Server.Engines.Plants;
using Server.Multis;
using Server.Targeting;
using System.Collections.Generic;
namespace Server.Items
{
    public enum DyeType
    {
        None,
        WindAzul,
        DullRuby,
        PoppieWhite,
        ZentoOrchid,
        UmbranViolet
    }
    public class SpecialNaturalDye : Item
    {
        private DyeType m_DyeType;
        private int m_UsesRemaining;
        private bool m_BooksOnly;
        [CommandProperty(AccessLevel.GameMaster)]
        public DyeType DyeType
        {
            get { return m_DyeType; }
            set
            {
                DyeType old = m_DyeType;
                m_DyeType = value;
                if (m_DyeType != old)
                    ValidateHue();
            }
        }
        [CommandProperty(AccessLevel.GameMaster)]
        public int UsesRemaining
        {
            get
            {
                return this.m_UsesRemaining;
            }
            set
            {
                this.m_UsesRemaining = value;
                this.InvalidateProperties();
            }
        }
        [CommandProperty(AccessLevel.GameMaster)]
        public bool BooksOnly
        {
            get
            {
                return this.m_BooksOnly;
            }
            set
            {
                this.m_BooksOnly = value;
                this.InvalidateProperties();
            }
        }
        [Constructable]
        public SpecialNaturalDye(DyeType type)
            : this(type, false)
        {
        }
        [Constructable]
        public SpecialNaturalDye(DyeType type, bool booksonly)
            : base(0x182B)
        {
            Weight = 1.0;
            DyeType = type;
            UsesRemaining = 5;
            BooksOnly = booksonly;
        }
        public void ValidateHue()
        {
            if (HueInfo.ContainsKey(this.DyeType))
            {
                Hue = HueInfo[this.DyeType].Item1;
            }
        }
        public SpecialNaturalDye(Serial serial)
            : base(serial)
        {
        }
        public override int LabelNumber
        {
            get
            {
                return 1112136;
            }
        }
        public override bool ForceShowProperties
        {
            get
            {
                return ObjectPropertyList.Enabled;
            }
        }
        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);
            list.Add(1060584, this.m_UsesRemaining.ToString()); // uses remaining: ~1_val~
            if (m_BooksOnly)
                list.Add(1157205); // Spellbook Only Dye
        }
        public override void AddNameProperty(ObjectPropertyList list)
        {
            if (this.DyeType == DyeType.None)
            {
                base.AddNameProperty(list);
            }
            else if (this.Amount > 1)
            {
                list.Add(1113276, "{0}\t{1}", this.Amount, String.Format("#{0}", HueInfo[this.DyeType].Item2));  // ~1_AMOUNT~ ~2_COLOR~ natural dyes
            }
            else
            {
                list.Add(1112137, String.Format("#{0}", HueInfo[this.DyeType].Item2));  // ~1_COLOR~ natural dye
            }
        }
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
            writer.Write((int)this.m_DyeType);
            writer.Write((int)this.m_UsesRemaining);
            writer.Write(m_BooksOnly);
        }
        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
            this.m_DyeType = (DyeType)reader.ReadInt();
            this.m_UsesRemaining = reader.ReadInt();
            this.m_BooksOnly = reader.ReadBool();
        }
        public override void OnDoubleClick(Mobile from)
        {
            from.SendLocalizedMessage(1112139); // Select the item you wish to dye.
            from.Target = new InternalTarget(this);
        }
        private class InternalTarget : Target
        {
            private readonly SpecialNaturalDye m_Item;
            public InternalTarget(SpecialNaturalDye item)
                : base(1, false, TargetFlags.None)
            {
                this.m_Item = item;
            }
            protected override void OnTarget(Mobile from, object targeted)
            {
                if (this.m_Item.Deleted)
                    return;
                Item item = targeted as Item;
                bool valid = false;
                if (item != null)
                {
                    if (m_Item.BooksOnly && !(item is Spellbook))
                    {
                        valid = false;
                    }
                    else
                    {
                        valid = (item is IDyable ||
                                      item is BaseBook || item is BaseClothing ||
                                      item is BaseJewel || item is BaseStatuette ||
                                      item is BaseWeapon || item is Runebook ||
                                      item is BaseTalisman || item is Spellbook ||
									  item.IsArtifact || BasePigmentsOfTokuno.IsValidItem(item));
                        if (!valid && item is BaseArmor)
                        {
                            CraftResourceType restype = CraftResources.GetType(((BaseArmor)item).Resource);
                            if ((CraftResourceType.Leather == restype || CraftResourceType.Metal == restype) &&
                                ArmorMaterialType.Bone != ((BaseArmor)item).MaterialType)
                            {
                                valid = true;
                            }
                        }
                        if (!valid && FurnitureAttribute.Check(item))
                        {
                            if (!from.InRange(this.m_Item.GetWorldLocation(), 1) || !from.InRange(item.GetWorldLocation(), 1))
                            {
                                from.SendLocalizedMessage(500446); // That is too far away.
                                return;
                            }
                            else
                            {
                                BaseHouse house = BaseHouse.FindHouseAt(item);
                                if (house == null || (!house.IsLockedDown(item) && !house.IsSecure(item)))
                                {
                                    from.SendLocalizedMessage(501022); // Furniture must be locked down to paint it.
                                    return;
                                }
                                else if (!house.IsCoOwner(from))
                                {
                                    from.SendLocalizedMessage(501023); // You must be the owner to use this item.
                                    return;
                                }
                                else
                                    valid = true;
                            }
                        }
                    }
                    if (valid)
                    {
                        item.Hue = m_Item.Hue;
                        from.PlaySound(0x23E);
                        if (--this.m_Item.UsesRemaining > 0)
                            this.m_Item.InvalidateProperties();
                        else
                            this.m_Item.Delete();
                        return;
                    }
                }
                from.SendLocalizedMessage(1042083); // You cannot dye that.
            }
        }
        public static Dictionary<DyeType, Tuple<int, int>> HueInfo;
        public static void Configure()
        {


Please complete the code given below. 
/*******************************************************************************
 * Copyright (c) 2020, 2021 Eurotech and/or its affiliates and others
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *  Eurotech
 *******************************************************************************/
package org.eclipse.kura.web.client.ui.security;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.eclipse.kura.web.client.messages.Messages;
import org.eclipse.kura.web.client.ui.AlertDialog;
import org.eclipse.kura.web.client.ui.AlertDialog.ConfirmListener;
import org.eclipse.kura.web.client.ui.Tab;
import org.eclipse.kura.web.client.util.request.RequestQueue;
import org.eclipse.kura.web.shared.DateUtils;
import org.eclipse.kura.web.shared.model.GwtKeystoreEntry;
import org.eclipse.kura.web.shared.model.GwtKeystoreEntry.Kind;
import org.eclipse.kura.web.shared.service.GwtCertificatesService;
import org.eclipse.kura.web.shared.service.GwtCertificatesServiceAsync;
import org.eclipse.kura.web.shared.service.GwtSecurityTokenService;
import org.eclipse.kura.web.shared.service.GwtSecurityTokenServiceAsync;
import org.gwtbootstrap3.client.ui.Button;
import org.gwtbootstrap3.client.ui.ListBox;
import org.gwtbootstrap3.client.ui.Modal;
import org.gwtbootstrap3.client.ui.ModalBody;
import org.gwtbootstrap3.client.ui.ModalFooter;
import org.gwtbootstrap3.client.ui.PanelFooter;
import org.gwtbootstrap3.client.ui.html.Span;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.HasRows;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;
public class CertificateListTabUi extends Composite implements Tab, CertificateModalListener {
    private static CertificateListTabUiUiBinder uiBinder = GWT.create(CertificateListTabUiUiBinder.class);
    interface CertificateListTabUiUiBinder extends UiBinder<Widget, CertificateListTabUi> {
    }
    private static final Messages MSGS = GWT.create(Messages.class);
    private final GwtSecurityTokenServiceAsync gwtXSRFService = GWT.create(GwtSecurityTokenService.class);
    private final GwtCertificatesServiceAsync gwtCertificatesService = GWT.create(GwtCertificatesService.class);
    @UiField
    Button refresh;
    @UiField
    Button add;
    @UiField
    Button uninstall;
    @UiField
    Modal certAddModal;
    @UiField
    ScrollPanel certAddModalBody;
    @UiField
    Button nextStepButton;
    @UiField
    Button applyModalButton;
    @UiField
    Button resetModalButton;
    @UiField
    Button closeModalButton;
    @UiField
    AlertDialog alertDialog;
    @UiField
    PanelFooter tablePanelFooter;
    @UiField
    CellTable<GwtKeystoreEntry> certificatesGrid;
    final SingleSelectionModel<GwtKeystoreEntry> selectionModel = new SingleSelectionModel<>();
    private final ListDataProvider<GwtKeystoreEntry> certificatesDataProvider = new ListDataProvider<>();
    private final SimplePager pager;
    private List<String> pids;
    private KeyPairTabUi keyPairTabUi;
    public CertificateListTabUi() {
        initWidget(uiBinder.createAndBindUi(this));
        this.pager = new SimplePager(TextLocation.CENTER, false, 0, true) {
            @Override
            public void nextPage() {
                setPage(getPage() + 1);
            }
            @Override
            public void setPageStart(int index) {
                final HasRows display = getDisplay();
                if (display != null) {
                    display.setVisibleRange(index, getPageSize());
                }
            }
        };
        this.pager.setPageSize(15);
        this.pager.setDisplay(this.certificatesGrid);
        this.tablePanelFooter.add(this.pager);
        initTable();
        initInterfaceButtons();
    }
    @Override
    public void setDirty(boolean flag) {
        // unused
    }
    @Override
    public boolean isDirty() {
        return false;
    }
    @Override
    public boolean isValid() {
        return true;
    }
    @Override
    public void refresh() {
        RequestQueue.submit(c -> this.gwtCertificatesService.listKeystoreServicePids(c.callback(resultPids -> {
            this.pids = resultPids;
            this.gwtCertificatesService.listEntries(c.callback(result -> {
                CertificateListTabUi.this.certificatesDataProvider.getList().clear();
                for (GwtKeystoreEntry pair : result) {
                    if (pair != null) {
                        this.certificatesDataProvider.getList().add(pair);
                    }
                }
                this.certificatesGrid.setVisible(!this.certificatesDataProvider.getList().isEmpty());
                this.selectionModel.clear();
                ColumnSortEvent.fire(this.certificatesGrid, this.certificatesGrid.getColumnSortList());
            }));
        })));
    }
    private void initTable() {
        TextColumn<GwtKeystoreEntry> col1 = new TextColumn<GwtKeystoreEntry>() {
            @Override
            public String getValue(GwtKeystoreEntry object) {
                return String.valueOf(object.getAlias());
            }
        };
        this.certificatesGrid.addColumn(col1, MSGS.certificateAlias());
        col1.setSortable(true);
        TextColumn<GwtKeystoreEntry> col2 = new TextColumn<GwtKeystoreEntry>() {
            @Override
            public String getValue(GwtKeystoreEntry object) {
                final Kind kind = object.getKind();
                if (kind == Kind.KEY_PAIR) {
                    return "Key Pair";
                } else if (kind == Kind.SECRET_KEY) {
                    return "Secret Key";
                } else if (kind == Kind.TRUSTED_CERT) {
                    return "Trusted Certificate";
                } else {
                    return "Unknown";
                }
            }
        };
        col2.setSortable(true);
        this.certificatesGrid.addColumn(col2, MSGS.certificateKind());
        TextColumn<GwtKeystoreEntry> col3 = new TextColumn<GwtKeystoreEntry>() {
            @Override
            public String getValue(GwtKeystoreEntry object) {
                return String.valueOf(object.getKeystoreName());
            }
        };
        col3.setSortable(true);
        this.certificatesGrid.addColumn(col3, MSGS.certificateKeystoreName());
        TextColumn<GwtKeystoreEntry> col4 = new TextColumn<GwtKeystoreEntry>() {
            @Override
            public String getValue(GwtKeystoreEntry object) {
                Date date = object.getValidityStartDate();
                return date != null ? DateUtils.formatDateTime(date) : "";
            }
        };
        this.certificatesGrid.addColumn(col4, MSGS.certificateValidityStart());
        col4.setSortable(true);
        TextColumn<GwtKeystoreEntry> col5 = new TextColumn<GwtKeystoreEntry>() {
            @Override
            public String getValue(GwtKeystoreEntry object) {
                Date date = object.getValidityEndDate();
                return date != null ? DateUtils.formatDateTime(date) : "";
            }
        };
        this.certificatesGrid.addColumn(col5, MSGS.certificateValidityEnd());
        col5.setSortable(true);
        this.selectionModel.addSelectionChangeHandler(
                e -> this.uninstall.setEnabled(this.selectionModel.getSelectedObject() != null));
        this.certificatesGrid.getColumnSortList().push(col2);
        this.certificatesGrid.addColumnSortHandler(getAliasSortHandler(col1));
        this.certificatesGrid.addColumnSortHandler(getTypeSortHandler(col2));
        this.certificatesGrid.addColumnSortHandler(getNameSortHandler(col3));
        this.certificatesGrid.addColumnSortHandler(getStartDateSortHandler(col4));
        this.certificatesGrid.addColumnSortHandler(getEndDateSortHandler(col5));
        this.certificatesDataProvider.addDataDisplay(this.certificatesGrid);
        this.certificatesGrid.setSelectionModel(this.selectionModel);
    }
    private <U extends Comparable<U>> Comparator<GwtKeystoreEntry> getComparator(
            Function<GwtKeystoreEntry, U> comparableElementSupplier) {
        return (o1, o2) -> {
            if (o1 == o2) {
                return 0;
            }
            if (o1 == null) {
                return -1;
            }
            if (o2 == null) {
                return 1;
            }
            U item1 = comparableElementSupplier.apply(o1);
            U item2 = comparableElementSupplier.apply(o2);
            if (item1 == item2) {
                return 0;
            }
            if (item1 == null) {
                return -1;
            }
            if (item2 == null) {
                return 1;
            }
            return item1.compareTo(item2);
        };
    }
    private ListHandler<GwtKeystoreEntry> getNameSortHandler(TextColumn<GwtKeystoreEntry> col3) {
        ListHandler<GwtKeystoreEntry> nameSortHandler = new ListHandler<>(this.certificatesDataProvider.getList());
        nameSortHandler.setComparator(col3, getComparator(GwtKeystoreEntry::getKeystoreName));
        return nameSortHandler;
    }
    private ListHandler<GwtKeystoreEntry> getTypeSortHandler(TextColumn<GwtKeystoreEntry> col2) {
        ListHandler<GwtKeystoreEntry> typeSortHandler = new ListHandler<>(this.certificatesDataProvider.getList());
        typeSortHandler.setComparator(col2, getComparator(entry -> entry.getKind().name()));
        return typeSortHandler;
    }
    private ListHandler<GwtKeystoreEntry> getAliasSortHandler(TextColumn<GwtKeystoreEntry> col1) {
        ListHandler<GwtKeystoreEntry> aliasSortHandler = new ListHandler<>(this.certificatesDataProvider.getList());
        aliasSortHandler.setComparator(col1, getComparator(GwtKeystoreEntry::getAlias));
        return aliasSortHandler;
    }
    private ListHandler<GwtKeystoreEntry> getStartDateSortHandler(TextColumn<GwtKeystoreEntry> col4) {
        ListHandler<GwtKeystoreEntry> startDateSortHandler = new ListHandler<>(this.certificatesDataProvider.getList());
        startDateSortHandler.setComparator(col4, getComparator(GwtKeystoreEntry::getValidityStartDate));
        return startDateSortHandler;
    }
    private ListHandler<GwtKeystoreEntry> getEndDateSortHandler(TextColumn<GwtKeystoreEntry> col5) {
        ListHandler<GwtKeystoreEntry> endDateSortHandler = new ListHandler<>(this.certificatesDataProvider.getList());
        endDateSortHandler.setComparator(col5, getComparator(GwtKeystoreEntry::getValidityEndDate));
        return endDateSortHandler;
    }
    private void initInterfaceButtons() {
        this.refresh.setText(MSGS.refresh());
        this.refresh.addClickHandler(event -> refresh());
        this.add.setText(MSGS.addButton());
        this.add.addClickHandler(event -> {
            initCertificateTypeSelection();
            this.certAddModal.show();
        });
        this.uninstall.setText(MSGS.delete());
        this.uninstall.addClickHandler(event -> {
            final GwtKeystoreEntry selected = this.selectionModel.getSelectedObject();
            if (selected != null) {


Please complete the code given below. 
//
// Microsoft.VisualBasic.* Test Cases
//
// Authors:
// Gert Driesen (drieseng@users.sourceforge.net)
//
// (c) 2006 Novell
//
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Globalization;
using System.IO;
using System.Text;
using NUnit.Framework;
namespace MonoTests.Microsoft.VisualBasic
{
	/// <summary>
	/// Test ICodeGenerator's GenerateCodeFromNamespace, along with a 
	/// minimal set CodeDom components.
	/// </summary>
	[TestFixture]
	public class CodeGeneratorFromNamespaceTest : CodeGeneratorTestBase
	{
		CodeNamespace codeNamespace = null;
		[SetUp]
		public void Init ()
		{
			InitBase ();
			codeNamespace = new CodeNamespace ();
		}
		
		protected override string Generate (CodeGeneratorOptions options)
		{
			StringWriter writer = new StringWriter ();
			writer.NewLine = NewLine;
			generator.GenerateCodeFromNamespace (codeNamespace, writer, options);
			writer.Close ();
			return writer.ToString ();
		}
		
		[Test]
		[ExpectedException (typeof (NullReferenceException))]
		public void NullNamespaceTest ()
		{
			codeNamespace = null;
			Generate ();
		}
		[Test]
		public void NullNamespaceNameTest ()
		{
			codeNamespace.Name = null;
			Assert.AreEqual ("\n", Generate ());
		}
		
		[Test]
		public void DefaultNamespaceTest ()
		{
			Assert.AreEqual ("\n", Generate ());
		}
		[Test]
		public void SimpleNamespaceTest ()
		{
			codeNamespace.Name = "A";
			Assert.AreEqual ("\nNamespace A\nEnd Namespace\n", Generate ());
		}
		[Test]
		public void InvalidNamespaceTest ()
		{
			codeNamespace.Name = "A,B";
			Assert.AreEqual ("\nNamespace A,B\nEnd Namespace\n", Generate ());
		}
		[Test]
		public void CommentOnlyNamespaceTest ()
		{
			CodeCommentStatement comment = new CodeCommentStatement ("a");
			codeNamespace.Comments.Add (comment);
			Assert.AreEqual ("\n'a\n", Generate ());
		}
		[Test]
		public void ImportsTest ()
		{
			codeNamespace.Imports.Add (new CodeNamespaceImport ("System"));
			codeNamespace.Imports.Add (new CodeNamespaceImport ("System.Collections"));
			Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
				"Imports System{0}" +
				"Imports System.Collections{0}" +
				"{0}", NewLine), Generate (), "#1");
			codeNamespace.Name = "A";
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"Imports System{0}" +
				"Imports System.Collections{0}" +
				"{0}" +
				"Namespace A{0}" +
				"End Namespace{0}", NewLine), Generate (), "#2");
			codeNamespace.Name = null;
			codeNamespace.Comments.Add (new CodeCommentStatement ("a"));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"Imports System{0}" +
				"Imports System.Collections{0}" +
				"{0}" +
				"'a{0}", NewLine), Generate (), "#3");
			codeNamespace.Name = "A";
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"Imports System{0}" +
				"Imports System.Collections{0}" +
				"{0}" +
				"'a{0}" +
				"Namespace A{0}" +
				"End Namespace{0}", NewLine), Generate (), "#4");
		}
		[Test]
		public void TypeTest ()
		{
			codeNamespace.Types.Add (new CodeTypeDeclaration ("Person"));
			Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
				"{0}" +
				"{0}" +
				"Public Class Person{0}" +
				"End Class{0}", NewLine), Generate (), "#A1");
			CodeGeneratorOptions options = new CodeGeneratorOptions ();
			options.BlankLinesBetweenMembers = false;
			Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
				"{0}" +
				"Public Class Person{0}" +
				"End Class{0}", NewLine), Generate (options), "#A2");
			codeNamespace.Name = "A";
			Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace A{0}" +
				"    {0}" +
				"    Public Class Person{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#B1");
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace A{0}" +
				"    Public Class Person{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (options), "#B2");
		}
#if NET_2_0
		[Test]
		public void Type_TypeParameters ()
		{
			codeNamespace.Name = "SomeNS";
			CodeTypeDeclaration type = new CodeTypeDeclaration ("SomeClass");
			codeNamespace.Types.Add (type);
			type.TypeParameters.Add (new CodeTypeParameter ("T"));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#1");
			type.TypeParameters.Add (new CodeTypeParameter ("As"));
			type.TypeParameters.Add (new CodeTypeParameter ("New"));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T, As, New){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#2");
			CodeTypeParameter typeParamR = new CodeTypeParameter ("R");
			typeParamR.Constraints.Add (new CodeTypeReference (typeof (IComparable)));
			type.TypeParameters.Add (typeParamR);
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T, As, New, R As System.IComparable){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#3");
			type.TypeParameters.Add (new CodeTypeParameter ("S"));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T, As, New, R As System.IComparable, S){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#4");
		}
		[Test]
		public void Type_TypeParameters_Constraints ()
		{
			codeNamespace.Name = "SomeNS";
			CodeTypeDeclaration type = new CodeTypeDeclaration ("SomeClass");
			codeNamespace.Types.Add (type);
			CodeTypeParameter typeParamT = new CodeTypeParameter ("T");
			typeParamT.Constraints.Add (new CodeTypeReference (typeof (IComparable)));
			type.TypeParameters.Add (typeParamT);
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T As System.IComparable){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#1");
			typeParamT.Constraints.Add (new CodeTypeReference (typeof (ICloneable)));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T As  {{System.IComparable, System.ICloneable}}){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#2");
			typeParamT.HasConstructorConstraint = true;
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T As  {{System.IComparable, System.ICloneable, New}}){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#3");
			CodeTypeParameter typeParamS = new CodeTypeParameter ("S");
			typeParamS.Constraints.Add (new CodeTypeReference (typeof (IDisposable)));
			type.TypeParameters.Add (typeParamS);
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T As  {{System.IComparable, System.ICloneable, New}}, S As System.IDisposable){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#4");
			CodeTypeParameter typeParamR = new CodeTypeParameter ("R");
			typeParamR.HasConstructorConstraint = true;
			type.TypeParameters.Add (typeParamR);
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T As  {{System.IComparable, System.ICloneable, New}}, S As System.IDisposable, R As New){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#5");
		}
		[Test]
		public void Type_TypeParameters_ConstructorConstraint ()
		{
			codeNamespace.Name = "SomeNS";
			CodeTypeDeclaration type = new CodeTypeDeclaration ("SomeClass");
			codeNamespace.Types.Add (type);
			CodeTypeParameter typeParam = new CodeTypeParameter ("T");
			typeParam.HasConstructorConstraint = true;
			type.TypeParameters.Add (typeParam);
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass(Of T As New){0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate ());
		}
		[Test]
		public void Method_TypeParameters ()
		{
			codeNamespace.Name = "SomeNS";
			CodeTypeDeclaration type = new CodeTypeDeclaration ("SomeClass");
			codeNamespace.Types.Add (type);
			CodeMemberMethod method = new CodeMemberMethod ();
			method.Name = "SomeMethod";
			type.Members.Add (method);
			method.TypeParameters.Add (new CodeTypeParameter ("T"));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass{0}" +
				"        {0}" +
				"        Private Sub SomeMethod(Of T)(){0}" +
				"        End Sub{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#1");
			method.TypeParameters.Add (new CodeTypeParameter ("As"));
			method.TypeParameters.Add (new CodeTypeParameter ("New"));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass{0}" +
				"        {0}" +
				"        Private Sub SomeMethod(Of T, As, New)(){0}" +
				"        End Sub{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#2");
			CodeTypeParameter typeParamR = new CodeTypeParameter ("R");
			typeParamR.Constraints.Add (new CodeTypeReference (typeof (IComparable)));
			method.TypeParameters.Add (typeParamR);
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass{0}" +
				"        {0}" +
				"        Private Sub SomeMethod(Of T, As, New, R As System.IComparable)(){0}" +
				"        End Sub{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#3");
			method.TypeParameters.Add (new CodeTypeParameter ("S"));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass{0}" +
				"        {0}" +
				"        Private Sub SomeMethod(Of T, As, New, R As System.IComparable, S)(){0}" +
				"        End Sub{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#4");
		}
		[Test]
		public void Method_TypeParameters_Constraints ()
		{
			codeNamespace.Name = "SomeNS";
			CodeTypeDeclaration type = new CodeTypeDeclaration ("SomeClass");
			codeNamespace.Types.Add (type);
			CodeMemberMethod method = new CodeMemberMethod ();
			method.Name = "SomeMethod";
			type.Members.Add (method);
			CodeTypeParameter typeParamT = new CodeTypeParameter ("T");
			typeParamT.Constraints.Add (new CodeTypeReference (typeof (IComparable)));
			method.TypeParameters.Add (typeParamT);
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass{0}" +
				"        {0}" +
				"        Private Sub SomeMethod(Of T As System.IComparable)(){0}" +
				"        End Sub{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#1");
			typeParamT.Constraints.Add (new CodeTypeReference (typeof (ICloneable)));
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass{0}" +
				"        {0}" +
				"        Private Sub SomeMethod(Of T As  {{System.IComparable, System.ICloneable}})(){0}" +
				"        End Sub{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#2");
			typeParamT.HasConstructorConstraint = true;
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +
				"    {0}" +
				"    Public Class SomeClass{0}" +
				"        {0}" +
				"        Private Sub SomeMethod(Of T As  {{System.IComparable, System.ICloneable, New}})(){0}" +
				"        End Sub{0}" +
				"    End Class{0}" +
				"End Namespace{0}", NewLine), Generate (), "#3");
			CodeTypeParameter typeParamS = new CodeTypeParameter ("S");
			typeParamS.Constraints.Add (new CodeTypeReference (typeof (IDisposable)));
			method.TypeParameters.Add (typeParamS);
			Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
				"{0}" +
				"Namespace SomeNS{0}" +


Please complete the code given below. 
"""Container and Namespace classes"""
import anydbm
import cPickle
import logging
import os
import time
import beaker.util as util
from beaker.exceptions import CreationAbortedError, MissingCacheParameter
from beaker.synchronization import _threading, file_synchronizer, \
     mutex_synchronizer, NameLock, null_synchronizer
__all__ = ['Value', 'Container', 'ContainerContext',
           'MemoryContainer', 'DBMContainer', 'NamespaceManager',
           'MemoryNamespaceManager', 'DBMNamespaceManager', 'FileContainer',
           'OpenResourceNamespaceManager',
           'FileNamespaceManager', 'CreationAbortedError']
logger = logging.getLogger('beaker.container')
if logger.isEnabledFor(logging.DEBUG):
    debug = logger.debug
else:
    def debug(message, *args):
        pass
class NamespaceManager(object):
    """Handles dictionary operations and locking for a namespace of
    values.
    
    The implementation for setting and retrieving the namespace data is
    handled by subclasses.
    
    NamespaceManager may be used alone, or may be privately accessed by
    one or more Container objects.  Container objects provide per-key
    services like expiration times and automatic recreation of values.
    
    Multiple NamespaceManagers created with a particular name will all
    share access to the same underlying datasource and will attempt to
    synchronize against a common mutex object.  The scope of this
    sharing may be within a single process or across multiple
    processes, depending on the type of NamespaceManager used.
    
    The NamespaceManager itself is generally threadsafe, except in the
    case of the DBMNamespaceManager in conjunction with the gdbm dbm
    implementation.
    """
    
    @classmethod
    def _init_dependencies(cls):
        pass
        
    def __init__(self, namespace):
        self._init_dependencies()
        self.namespace = namespace
        
    def get_creation_lock(self, key):
        raise NotImplementedError()
    def do_remove(self):
        raise NotImplementedError()
    def acquire_read_lock(self):
        pass
    def release_read_lock(self):
        pass
    def acquire_write_lock(self, wait=True):
        return True
    def release_write_lock(self):
        pass
    def has_key(self, key):
        return self.__contains__(key)
    def __getitem__(self, key):
        raise NotImplementedError()
        
    def __setitem__(self, key, value):
        raise NotImplementedError()
    
    def set_value(self, key, value, expiretime=None):
        """Optional set_value() method called by Value.
        
        Allows an expiretime to be passed, for namespace
        implementations which can prune their collections
        using expiretime.
        
        """
        self[key] = value
        
    def __contains__(self, key):
        raise NotImplementedError()
    def __delitem__(self, key):
        raise NotImplementedError()
    
    def keys(self):
        raise NotImplementedError()
    
    def remove(self):
        self.do_remove()
        
class OpenResourceNamespaceManager(NamespaceManager):
    """A NamespaceManager where read/write operations require opening/
    closing of a resource which is possibly mutexed.
    
    """
    def __init__(self, namespace):
        NamespaceManager.__init__(self, namespace)
        self.access_lock = self.get_access_lock()
        self.openers = 0
        self.mutex = _threading.Lock()
    def get_access_lock(self):
        raise NotImplementedError()
    def do_open(self, flags): 
        raise NotImplementedError()
    def do_close(self): 
        raise NotImplementedError()
    def acquire_read_lock(self): 
        self.access_lock.acquire_read_lock()
        try:
            self.open('r', checkcount = True)
        except:
            self.access_lock.release_read_lock()
            raise
            
    def release_read_lock(self):
        try:
            self.close(checkcount = True)
        finally:
            self.access_lock.release_read_lock()
        
    def acquire_write_lock(self, wait=True): 
        r = self.access_lock.acquire_write_lock(wait)
        try:
            if (wait or r): 
                self.open('c', checkcount = True)
            return r
        except:
            self.access_lock.release_write_lock()
            raise
            
    def release_write_lock(self): 
        try:
            self.close(checkcount=True)
        finally:
            self.access_lock.release_write_lock()
    def open(self, flags, checkcount=False):
        self.mutex.acquire()
        try:
            if checkcount:
                if self.openers == 0: 
                    self.do_open(flags)
                self.openers += 1
            else:
                self.do_open(flags)
                self.openers = 1
        finally:
            self.mutex.release()
    def close(self, checkcount=False):
        self.mutex.acquire()
        try:
            if checkcount:
                self.openers -= 1
                if self.openers == 0: 
                    self.do_close()
            else:
                if self.openers > 0:
                    self.do_close()
                self.openers = 0
        finally:
            self.mutex.release()
    def remove(self):
        self.access_lock.acquire_write_lock()
        try:
            self.close(checkcount=False)
            self.do_remove()
        finally:
            self.access_lock.release_write_lock()
class Value(object):
    __slots__ = 'key', 'createfunc', 'expiretime', 'expire_argument', 'starttime', 'storedtime',\
                'namespace'
    def __init__(self, key, namespace, createfunc=None, expiretime=None, starttime=None):
        self.key = key
        self.createfunc = createfunc
        self.expire_argument = expiretime
        self.starttime = starttime
        self.storedtime = -1
        self.namespace = namespace
    def has_value(self):
        """return true if the container has a value stored.
        This is regardless of it being expired or not.
        """
        self.namespace.acquire_read_lock()
        try:    
            return self.namespace.has_key(self.key)
        finally:
            self.namespace.release_read_lock()
    def can_have_value(self):
        return self.has_current_value() or self.createfunc is not None  
    def has_current_value(self):
        self.namespace.acquire_read_lock()
        try:    
            has_value = self.namespace.has_key(self.key)
            if has_value:
                try:
                    stored, expired, value = self._get_value()
                    return not self._is_expired(stored, expired)
                except KeyError:
                    pass
            return False
        finally:
            self.namespace.release_read_lock()
    def _is_expired(self, storedtime, expiretime):
        """Return true if this container's value is expired."""
        return (
            (
                self.starttime is not None and
                storedtime < self.starttime
            )
            or
            (
                expiretime is not None and
                time.time() >= expiretime + storedtime
            )
        )
    def get_value(self):
        self.namespace.acquire_read_lock()
        try:
            has_value = self.has_value()
            if has_value:
                try:
                    stored, expired, value = self._get_value()
                    if not self._is_expired(stored, expired):
                        return value
                except KeyError:
                    # guard against un-mutexed backends raising KeyError
                    has_value = False
                    
            if not self.createfunc:
                raise KeyError(self.key)
        finally:
            self.namespace.release_read_lock()
        has_createlock = False
        creation_lock = self.namespace.get_creation_lock(self.key)
        if has_value:
            if not creation_lock.acquire(wait=False):
                debug("get_value returning old value while new one is created")
                return value
            else:
                debug("lock_creatfunc (didnt wait)")
                has_createlock = True
        if not has_createlock:
            debug("lock_createfunc (waiting)")
            creation_lock.acquire()
            debug("lock_createfunc (waited)")
        try:
            # see if someone created the value already
            self.namespace.acquire_read_lock()
            try:
                if self.has_value():
                    try:
                        stored, expired, value = self._get_value()
                        if not self._is_expired(stored, expired):
                            return value
                    except KeyError:
                        # guard against un-mutexed backends raising KeyError
                        pass
            finally:
                self.namespace.release_read_lock()
            debug("get_value creating new value")
            v = self.createfunc()
            self.set_value(v)
            return v
        finally:
            creation_lock.release()
            debug("released create lock")
    def _get_value(self):
        value = self.namespace[self.key]
        try:
            stored, expired, value = value
        except ValueError:
            if not len(value) == 2:
                raise
            # Old format: upgrade
            stored, value = value
            expired = self.expire_argument
            debug("get_value upgrading time %r expire time %r", stored, self.expire_argument)
            self.namespace.release_read_lock()
            self.set_value(value, stored)
            self.namespace.acquire_read_lock()
        except TypeError:
            # occurs when the value is None.  memcached 
            # may yank the rug from under us in which case 
            # that's the result
            raise KeyError(self.key)            
        return stored, expired, value
    def set_value(self, value, storedtime=None):
        self.namespace.acquire_write_lock()
        try:
            if storedtime is None:
                storedtime = time.time()
            debug("set_value stored time %r expire time %r", storedtime, self.expire_argument)
            self.namespace.set_value(self.key, (storedtime, self.expire_argument, value))
        finally:
            self.namespace.release_write_lock()
    def clear_value(self):
        self.namespace.acquire_write_lock()
        try:
            debug("clear_value")
            if self.namespace.has_key(self.key):
                try:
                    del self.namespace[self.key]
                except KeyError:
                    # guard against un-mutexed backends raising KeyError
                    pass
            self.storedtime = -1
        finally:
            self.namespace.release_write_lock()
class AbstractDictionaryNSManager(NamespaceManager):
    """A subclassable NamespaceManager that places data in a dictionary.
    
    Subclasses should provide a "dictionary" attribute or descriptor
    which returns a dict-like object.   The dictionary will store keys
    that are local to the "namespace" attribute of this manager, so
    ensure that the dictionary will not be used by any other namespace.
    e.g.::
    
        import collections
        cached_data = collections.defaultdict(dict)
        
        class MyDictionaryManager(AbstractDictionaryNSManager):
            def __init__(self, namespace):
                AbstractDictionaryNSManager.__init__(self, namespace)
                self.dictionary = cached_data[self.namespace]
                
    The above stores data in a global dictionary called "cached_data",
    which is structured as a dictionary of dictionaries, keyed
    first on namespace name to a sub-dictionary, then on actual
    cache key to value.
    
    """
    
    def get_creation_lock(self, key):
        return NameLock(
            identifier="memorynamespace/funclock/%s/%s" % (self.namespace, key),
            reentrant=True
        )
    def __getitem__(self, key): 
        return self.dictionary[key]
    def __contains__(self, key): 
        return self.dictionary.__contains__(key)
    def has_key(self, key): 
        return self.dictionary.__contains__(key)
        
    def __setitem__(self, key, value):
        self.dictionary[key] = value
    
    def __delitem__(self, key):
        del self.dictionary[key]
    def do_remove(self):
        self.dictionary.clear()
        
    def keys(self):
        return self.dictionary.keys()
    
class MemoryNamespaceManager(AbstractDictionaryNSManager):
    namespaces = util.SyncDict()
    def __init__(self, namespace, **kwargs):
        AbstractDictionaryNSManager.__init__(self, namespace)
        self.dictionary = MemoryNamespaceManager.namespaces.get(self.namespace,
                                                                dict)
class DBMNamespaceManager(OpenResourceNamespaceManager):
    def __init__(self, namespace, dbmmodule=None, data_dir=None, 
            dbm_dir=None, lock_dir=None, digest_filenames=True, **kwargs):
        self.digest_filenames = digest_filenames
        
        if not dbm_dir and not data_dir:
            raise MissingCacheParameter("data_dir or dbm_dir is required")
        elif dbm_dir:
            self.dbm_dir = dbm_dir
        else:
            self.dbm_dir = data_dir + "/container_dbm"
        util.verify_directory(self.dbm_dir)
        
        if not lock_dir and not data_dir:
            raise MissingCacheParameter("data_dir or lock_dir is required")
        elif lock_dir:
            self.lock_dir = lock_dir
        else:
            self.lock_dir = data_dir + "/container_dbm_lock"
        util.verify_directory(self.lock_dir)
        self.dbmmodule = dbmmodule or anydbm
        self.dbm = None
        OpenResourceNamespaceManager.__init__(self, namespace)
        self.file = util.encoded_path(root= self.dbm_dir,
                                      identifiers=[self.namespace],
                                      extension='.dbm',
                                      digest_filenames=self.digest_filenames)
        
        debug("data file %s", self.file)
        self._checkfile()
    def get_access_lock(self):
        return file_synchronizer(identifier=self.namespace,
                                 lock_dir=self.lock_dir)
                                 
    def get_creation_lock(self, key):
        return file_synchronizer(
                    identifier = "dbmcontainer/funclock/%s" % self.namespace, 
                    lock_dir=self.lock_dir
                )
    def file_exists(self, file):
        if os.access(file, os.F_OK): 
            return True
        else:
            for ext in ('db', 'dat', 'pag', 'dir'):
                if os.access(file + os.extsep + ext, os.F_OK):
                    return True
                    
        return False
    
    def _checkfile(self):
        if not self.file_exists(self.file):
            g = self.dbmmodule.open(self.file, 'c') 
            g.close()
                
    def get_filenames(self):
        list = []
        if os.access(self.file, os.F_OK):
            list.append(self.file)
            
        for ext in ('pag', 'dir', 'db', 'dat'):


Please complete the code given below. 
/*
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package javax.swing;
import java.awt.*;
import java.awt.image.*;
import java.beans.ConstructorProperties;
import java.beans.Transient;
import java.net.URL;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.util.Locale;
import javax.accessibility.*;
import sun.awt.AppContext;
import java.lang.reflect.Field;
import java.security.PrivilegedAction;
import java.security.AccessController;
/**
 * An implementation of the Icon interface that paints Icons
 * from Images. Images that are created from a URL, filename or byte array
 * are preloaded using MediaTracker to monitor the loaded state
 * of the image.
 *
 * <p>
 * For further information and examples of using image icons, see
 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/icon.html">How to Use Icons</a>
 * in <em>The Java Tutorial.</em>
 *
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @author Jeff Dinkins
 * @author Lynn Monsanto
 */
public class ImageIcon implements Icon, Serializable, Accessible {
    /* Keep references to the filename and location so that
     * alternate persistence schemes have the option to archive
     * images symbolically rather than including the image data
     * in the archive.
     */
    transient private String filename;
    transient private URL location;
    transient Image image;
    transient int loadStatus = 0;
    ImageObserver imageObserver;
    String description = null;
    protected final static Component component;
    protected final static MediaTracker tracker;
    static {
        component = new Component() {};
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            public Object run() {
                try {
                    // 6482575 - clear the appContext field so as not to leak it
                    Field appContextField =
                                 Component.class.getDeclaredField("appContext");
                    appContextField.setAccessible(true);
                    appContextField.set(component, null);
                }
                catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
                catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
        tracker = new MediaTracker(component);
    }
    /**
     * Id used in loading images from MediaTracker.
     */
    private static int mediaTrackerID;
    private final static Object TRACKER_KEY = new StringBuilder("TRACKER_KEY");
    int width = -1;
    int height = -1;
    /**
     * Creates an ImageIcon from the specified file. The image will
     * be preloaded by using MediaTracker to monitor the loading state
     * of the image.
     * @param filename the name of the file containing the image
     * @param description a brief textual description of the image
     * @see #ImageIcon(String)
     */
    public ImageIcon(String filename, String description) {
        image = Toolkit.getDefaultToolkit().getImage(filename);
        if (image == null) {
            return;
        }
        this.filename = filename;
        this.description = description;
        loadImage(image);
    }
    /**
     * Creates an ImageIcon from the specified file. The image will
     * be preloaded by using MediaTracker to monitor the loading state
     * of the image. The specified String can be a file name or a
     * file path. When specifying a path, use the Internet-standard
     * forward-slash ("/") as a separator.
     * (The string is converted to an URL, so the forward-slash works
     * on all systems.)
     * For example, specify:
     * <pre>
     *    new ImageIcon("images/myImage.gif") </pre>
     * The description is initialized to the <code>filename</code> string.
     *
     * @param filename a String specifying a filename or path
     * @see #getDescription
     */
    @ConstructorProperties({"description"})
    public ImageIcon (String filename) {
        this(filename, filename);
    }
    /**
     * Creates an ImageIcon from the specified URL. The image will
     * be preloaded by using MediaTracker to monitor the loaded state
     * of the image.
     * @param location the URL for the image
     * @param description a brief textual description of the image
     * @see #ImageIcon(String)
     */
    public ImageIcon(URL location, String description) {
        image = Toolkit.getDefaultToolkit().getImage(location);
        if (image == null) {
            return;
        }
        this.location = location;
        this.description = description;
        loadImage(image);
    }
    /**
     * Creates an ImageIcon from the specified URL. The image will
     * be preloaded by using MediaTracker to monitor the loaded state
     * of the image.
     * The icon's description is initialized to be
     * a string representation of the URL.
     * @param location the URL for the image
     * @see #getDescription
     */
    public ImageIcon (URL location) {
        this(location, location.toExternalForm());
    }
    /**
     * Creates an ImageIcon from the image.
     * @param image the image
     * @param description a brief textual description of the image
     */
    public ImageIcon(Image image, String description) {
        this(image);
        this.description = description;
    }
    /**
     * Creates an ImageIcon from an image object.
     * If the image has a "comment" property that is a string,
     * then the string is used as the description of this icon.
     * @param image the image
     * @see #getDescription
     * @see java.awt.Image#getProperty
     */
    public ImageIcon (Image image) {
        this.image = image;
        Object o = image.getProperty("comment", imageObserver);
        if (o instanceof String) {
            description = (String) o;
        }
        loadImage(image);
    }
    /**
     * Creates an ImageIcon from an array of bytes which were
     * read from an image file containing a supported image format,
     * such as GIF, JPEG, or (as of 1.3) PNG.
     * Normally this array is created
     * by reading an image using Class.getResourceAsStream(), but
     * the byte array may also be statically stored in a class.
     *
     * @param  imageData an array of pixels in an image format supported
     *         by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
     * @param  description a brief textual description of the image
     * @see    java.awt.Toolkit#createImage
     */
    public ImageIcon (byte[] imageData, String description) {
        this.image = Toolkit.getDefaultToolkit().createImage(imageData);
        if (image == null) {
            return;
        }
        this.description = description;
        loadImage(image);
    }
    /**
     * Creates an ImageIcon from an array of bytes which were
     * read from an image file containing a supported image format,
     * such as GIF, JPEG, or (as of 1.3) PNG.
     * Normally this array is created
     * by reading an image using Class.getResourceAsStream(), but
     * the byte array may also be statically stored in a class.
     * If the resulting image has a "comment" property that is a string,
     * then the string is used as the description of this icon.
     *
     * @param  imageData an array of pixels in an image format supported by
     *             the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
     * @see    java.awt.Toolkit#createImage
     * @see #getDescription
     * @see java.awt.Image#getProperty
     */
    public ImageIcon (byte[] imageData) {
        this.image = Toolkit.getDefaultToolkit().createImage(imageData);
        if (image == null) {
            return;
        }
        Object o = image.getProperty("comment", imageObserver);
        if (o instanceof String) {
            description = (String) o;
        }
        loadImage(image);
    }
    /**
     * Creates an uninitialized image icon.
     */
    public ImageIcon() {
    }
    /**
     * Loads the image, returning only when the image is loaded.
     * @param image the image
     */
    protected void loadImage(Image image) {
        MediaTracker mTracker = getTracker();
        synchronized(mTracker) {
            int id = getNextID();
            mTracker.addImage(image, id);
            try {
                mTracker.waitForID(id, 0);
            } catch (InterruptedException e) {
                System.out.println("INTERRUPTED while loading Image");
            }
            loadStatus = mTracker.statusID(id, false);
            mTracker.removeImage(image, id);
            width = image.getWidth(imageObserver);
            height = image.getHeight(imageObserver);
        }
    }
    /**
     * Returns an ID to use with the MediaTracker in loading an image.
     */
    private int getNextID() {
        synchronized(getTracker()) {
            return ++mediaTrackerID;
        }
    }
    /**
     * Returns the MediaTracker for the current AppContext, creating a new
     * MediaTracker if necessary.
     */
    private MediaTracker getTracker() {
        Object trackerObj;
        AppContext ac = AppContext.getAppContext();
        // Opt: Only synchronize if trackerObj comes back null?
        // If null, synchronize, re-check for null, and put new tracker
        synchronized(ac) {
            trackerObj = ac.get(TRACKER_KEY);
            if (trackerObj == null) {
                Component comp = new Component() {};
                trackerObj = new MediaTracker(comp);
                ac.put(TRACKER_KEY, trackerObj);
            }
        }
        return (MediaTracker) trackerObj;
    }
    /**
     * Returns the status of the image loading operation.
     * @return the loading status as defined by java.awt.MediaTracker
     * @see java.awt.MediaTracker#ABORTED
     * @see java.awt.MediaTracker#ERRORED
     * @see java.awt.MediaTracker#COMPLETE
     */
    public int getImageLoadStatus() {
        return loadStatus;
    }
    /**
     * Returns this icon's <code>Image</code>.
     * @return the <code>Image</code> object for this <code>ImageIcon</code>
     */
    @Transient
    public Image getImage() {
        return image;
    }
    /**
     * Sets the image displayed by this icon.
     * @param image the image
     */
    public void setImage(Image image) {
        this.image = image;
        loadImage(image);
    }
    /**
     * Gets the description of the image.  This is meant to be a brief
     * textual description of the object.  For example, it might be
     * presented to a blind user to give an indication of the purpose
     * of the image.
     * The description may be null.
     *
     * @return a brief textual description of the image
     */
    public String getDescription() {
        return description;
    }
    /**
     * Sets the description of the image.  This is meant to be a brief
     * textual description of the object.  For example, it might be
     * presented to a blind user to give an indication of the purpose
     * of the image.
     * @param description a brief textual description of the image
     */
    public void setDescription(String description) {
        this.description = description;
    }
    /**
     * Paints the icon.
     * The top-left corner of the icon is drawn at
     * the point (<code>x</code>, <code>y</code>)
     * in the coordinate space of the graphics context <code>g</code>.
     * If this icon has no image observer,
     * this method uses the <code>c</code> component
     * as the observer.
     *
     * @param c the component to be used as the observer
     *          if this icon has no image observer
     * @param g the graphics context
     * @param x the X coordinate of the icon's top-left corner
     * @param y the Y coordinate of the icon's top-left corner
     */
    public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
        if(imageObserver == null) {
           g.drawImage(image, x, y, c);
        } else {
           g.drawImage(image, x, y, imageObserver);
        }
    }
    /**
     * Gets the width of the icon.
     *
     * @return the width in pixels of this icon
     */
    public int getIconWidth() {
        return width;
    }
    /**
     * Gets the height of the icon.
     *
     * @return the height in pixels of this icon
     */
    public int getIconHeight() {
        return height;
    }
    /**
     * Sets the image observer for the image.  Set this
     * property if the ImageIcon contains an animated GIF, so
     * the observer is notified to update its display.
     * For example:
     * <pre>
     *     icon = new ImageIcon(...)
     *     button.setIcon(icon);
     *     icon.setImageObserver(button);
     * </pre>
     *
     * @param observer the image observer
     */
    public void setImageObserver(ImageObserver observer) {
        imageObserver = observer;
    }
    /**
     * Returns the image observer for the image.
     *
     * @return the image observer, which may be null
     */
    @Transient
    public ImageObserver getImageObserver() {
        return imageObserver;
    }
    /**
     * Returns a string representation of this image.
     *
     * @return a string representing this image
     */
    public String toString() {


Please complete the code given below. 
# -*- coding: utf-8 -*-
from ast import literal_eval
from pprint import pformat
import os
import shutil
from errbot import BotPlugin, botcmd
from errbot.plugin_manager import PluginConfigurationException, PluginActivationException
from errbot.repo_manager import RepoException
class Plugins(BotPlugin):
    @botcmd(admin_only=True)
    def repos_install(self, _, args):
        """ install a plugin repository from the given source or a known public repo (see !repos to find those).
        for example from a known repo : !install err-codebot
        for example a git url : git@github.com:gbin/plugin.git
        or an url towards a tar.gz archive : http://www.gootz.net/plugin-latest.tar.gz
        """
        args = args.strip()
        if not args:
            yield "Please specify a repository listed in '!repos' or " \
                  "give me the URL to a git repository that I should clone for you."
            return
        try:
            yield "Installing %s..." % args
            local_path = self._bot.repo_manager.install_repo(args)
            errors = self._bot.plugin_manager.update_dynamic_plugins()
            if errors:
                yield 'Some plugins are generating errors:\n' + '\n'.join(errors.values())
                # if the load of the plugin failed, uninstall cleanly teh repo
                for path in errors.keys():
                    if path.startswith(local_path):
                        yield 'Removing %s as it did not load correctly.' % local_path
                        shutil.rmtree(local_path)
            else:
                yield ("A new plugin repository has been installed correctly from "
                       "%s. Refreshing the plugins commands..." % args)
            loading_errors = self._bot.plugin_manager.activate_non_started_plugins()
            if loading_errors:
                yield loading_errors
            yield "Plugins reloaded."
        except RepoException as re:
            yield "Error installing the repo: %s" % re
    @botcmd(admin_only=True)
    def repos_uninstall(self, _, repo_name):
        """ uninstall a plugin repository by name.
        """
        if not repo_name.strip():
            yield "You should have a repo name as argument"
            return
        repos = self._bot.repo_manager.get_installed_plugin_repos()
        if repo_name not in repos:
            yield "This repo is not installed check with " + self._bot.prefix + "repos the list of installed ones"
            return
        plugin_path = os.path.join(self._bot.repo_manager.plugin_dir, repo_name)
        self._bot.plugin_manager.remove_plugins_from_path(plugin_path)
        self._bot.repo_manager.uninstall_repo(repo_name)
        yield 'Repo %s removed.' % repo_name
    @botcmd(template='repos')
    def repos(self, _, args):
        """ list the current active plugin repositories
        """
        installed_repos = self._bot.repo_manager.get_installed_plugin_repos()
        all_names = [name for name in installed_repos]
        repos = {'repos': []}
        for repo_name in all_names:
            installed = False
            if repo_name in installed_repos:
                installed = True
            from_index = self._bot.repo_manager.get_repo_from_index(repo_name)
            if from_index is not None:
                description = '\n'.join(('%s: %s' % (plug.name, plug.documentation) for plug in from_index))
            else:
                description = 'No description.'
            # installed, public, name, desc
            repos['repos'].append((installed, from_index is not None, repo_name, description))
        return repos
    @botcmd(template='repos2')
    def repos_search(self, _, args):
        """ Searches the repo index.
        for example: !repos search jenkins
        """
        if not args:
            # TODO(gbin): return all the repos.
            return {'error': "Please specify a keyword."}
        return {'repos': self._bot.repo_manager.search_repos(args)}
    @botcmd(split_args_with=' ', admin_only=True)
    def repos_update(self, _, args):
        """ update the bot and/or plugins
        use : !repos update all
        to update everything
        or : !repos update repo_name repo_name ...
        to update selectively some repos
        """
        if 'all' in args:
            results = self._bot.repo_manager.update_all_repos()
        else:
            results = self._bot.repo_manager.update_repos(args)
        yield "Start updating ... "
        for d, success, feedback in results:
            if success:
                yield "Update of %s succeeded...\n\n%s\n\n" % (d, feedback)
            else:
                yield "Update of %s failed...\n\n%s" % (d, feedback)
            for plugin in self._bot.plugin_manager.getAllPlugins():
                if plugin.path.startswith(d) and hasattr(plugin, 'is_activated') and plugin.is_activated:
                    name = plugin.name
                    yield '/me is reloading plugin %s' % name
                    try:
                        self._bot.plugin_manager.reload_plugin_by_name(plugin.name)
                        yield "Plugin %s reloaded." % plugin.name
                    except PluginActivationException as pae:
                        yield 'Error reactivating plugin %s: %s' % (plugin.name, pae)
        yield "Done."
    @botcmd(split_args_with=' ', admin_only=True)
    def plugin_config(self, _, args):
        """ configure or get the configuration / configuration template for a specific plugin
        ie.
        !plugin config ExampleBot
        could return a template if it is not configured:
        {'LOGIN': 'example@example.com', 'PASSWORD': 'password', 'DIRECTORY': '/toto'}
        Copy paste, adapt so can configure the plugin :
        !plugin config ExampleBot {'LOGIN': 'my@email.com', 'PASSWORD': 'myrealpassword', 'DIRECTORY': '/tmp'}
        It will then reload the plugin with this config.
        You can at any moment retrieve the current values:
        !plugin config ExampleBot
        should return :
        {'LOGIN': 'my@email.com', 'PASSWORD': 'myrealpassword', 'DIRECTORY': '/tmp'}
        """
        plugin_name = args[0]
        if self._bot.plugin_manager.is_plugin_blacklisted(plugin_name):
            return 'Load this plugin first with ' + self._bot.prefix + 'load %s' % plugin_name
        obj = self._bot.plugin_manager.get_plugin_obj_by_name(plugin_name)
        if obj is None:
            return 'Unknown plugin or the plugin could not load %s' % plugin_name
        template_obj = obj.get_configuration_template()
        if template_obj is None:
            return 'This plugin is not configurable.'
        if len(args) == 1:
            response = ("Default configuration for this plugin (you can copy and paste "
                        "this directly as a command):\n\n"
                        "```\n{prefix}plugin config {plugin_name} \n{config}\n```").format(
                prefix=self._bot.prefix, plugin_name=plugin_name, config=pformat(template_obj))
            current_config = self._bot.plugin_manager.get_plugin_configuration(plugin_name)
            if current_config:
                response += ("\n\nCurrent configuration:\n\n"
                             "```\n{prefix}plugin config {plugin_name} \n{config}\n```").format(
                    prefix=self._bot.prefix, plugin_name=plugin_name, config=pformat(current_config))
            return response
        # noinspection PyBroadException
        try:
            real_config_obj = literal_eval(' '.join(args[1:]))
        except Exception:
            self.log.exception('Invalid expression for the configuration of the plugin')
            return 'Syntax error in the given configuration'
        if type(real_config_obj) != type(template_obj):
            return 'It looks fishy, your config type is not the same as the template !'
        self._bot.plugin_manager.set_plugin_configuration(plugin_name, real_config_obj)
        try:
            self._bot.plugin_manager.deactivate_plugin(plugin_name)
        except PluginActivationException as pae:
            return 'Error deactivating %s: %s' % (plugin_name, pae)
        try:
            self._bot.plugin_manager.activate_plugin(plugin_name)
        except PluginConfigurationException as ce:
            self.log.debug('Invalid configuration for the plugin, reverting the plugin to unconfigured.')
            self._bot.plugin_manager.set_plugin_configuration(plugin_name, None)
            return 'Incorrect plugin configuration: %s' % ce
        except PluginActivationException as pae:
            return 'Error activating plugin: %s' % pae
        return 'Plugin configuration done.'
    def formatted_plugin_list(self, active_only=True):
        """
        Return a formatted, plain-text list of loaded plugins.
        When active_only=True, this will only return plugins which
        are actually active. Otherwise, it will also include inactive
        (blacklisted) plugins.
        """
        if active_only:
            all_plugins = self._bot.plugin_manager.get_all_active_plugin_names()
        else:


Please complete the code given below. 
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
                    'supported_by': 'community',
                    'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_system_switch_interface
short_description: Configure software switch interfaces by grouping physical and WiFi interfaces in Fortinet's FortiOS and FortiGate.
description:
    - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
      user to set and modify system feature and switch_interface category.
      Examples include all parameters and values need to be adjusted to datasources before usage.
      Tested with FOS v6.0.5
version_added: "2.9"
author:
    - Miguel Angel Munoz (@mamunozgonzalez)
    - Nicolas Thomas (@thomnico)
notes:
    - Requires fortiosapi library developed by Fortinet
    - Run as a local_action in your playbook
requirements:
    - fortiosapi>=0.9.8
options:
    host:
        description:
            - FortiOS or FortiGate IP address.
        type: str
        required: false
    username:
        description:
            - FortiOS or FortiGate username.
        type: str
        required: false
    password:
        description:
            - FortiOS or FortiGate password.
        type: str
        default: ""
    vdom:
        description:
            - Virtual domain, among those defined previously. A vdom is a
              virtual instance of the FortiGate that can be configured and
              used as a different unit.
        type: str
        default: root
    https:
        description:
            - Indicates if the requests towards FortiGate must use HTTPS protocol.
        type: bool
        default: true
    ssl_verify:
        description:
            - Ensures FortiGate certificate must be verified by a proper CA.
        type: bool
        default: true
    state:
        description:
            - Indicates whether to create or remove the object.
        type: str
        required: true
        choices:
            - present
            - absent
    system_switch_interface:
        description:
            - Configure software switch interfaces by grouping physical and WiFi interfaces.
        default: null
        type: dict
        suboptions:
            intra_switch_policy:
                description:
                    - Allow any traffic between switch interfaces or require firewall policies to allow traffic between switch interfaces.
                type: str
                choices:
                    - implicit
                    - explicit
            member:
                description:
                    - Names of the interfaces that belong to the virtual switch.
                type: list
                suboptions:
                    interface_name:
                        description:
                            - Physical interface name. Source system.interface.name.
                        type: str
            name:
                description:
                    - Interface name (name cannot be in use by any other interfaces, VLANs, or inter-VDOM links).
                required: true
                type: str
            span:
                description:
                    - Enable/disable port spanning. Port spanning echoes traffic received by the software switch to the span destination port.
                type: str
                choices:
                    - disable
                    - enable
            span_dest_port:
                description:
                    - SPAN destination port name. All traffic on the SPAN source ports is echoed to the SPAN destination port. Source system.interface.name.
                type: str
            span_direction:
                description:
                    - "The direction in which the SPAN port operates, either: rx, tx, or both."
                type: str
                choices:
                    - rx
                    - tx
                    - both
            span_source_port:
                description:
                    - Physical interface name. Port spanning echoes all traffic on the SPAN source ports to the SPAN destination port.
                type: list
                suboptions:
                    interface_name:
                        description:
                            - Physical interface name. Source system.interface.name.
                        type: str
            type:
                description:
                    - "Type of switch based on functionality: switch for normal functionality, or hub to duplicate packets to all port members."
                type: str
                choices:
                    - switch
                    - hub
            vdom:
                description:
                    - VDOM that the software switch belongs to. Source system.vdom.name.
                type: str
'''
EXAMPLES = '''
- hosts: localhost
  vars:
   host: "192.168.122.40"
   username: "admin"
   password: ""
   vdom: "root"
   ssl_verify: "False"
  tasks:
  - name: Configure software switch interfaces by grouping physical and WiFi interfaces.
    fortios_system_switch_interface:
      host:  "{{ host }}"
      username: "{{ username }}"
      password: "{{ password }}"
      vdom:  "{{ vdom }}"
      https: "False"
      state: "present"
      system_switch_interface:
        intra_switch_policy: "implicit"
        member:
         -
            interface_name: "<your_own_value> (source system.interface.name)"
        name: "default_name_6"
        span: "disable"
        span_dest_port: "<your_own_value> (source system.interface.name)"
        span_direction: "rx"
        span_source_port:
         -
            interface_name: "<your_own_value> (source system.interface.name)"
        type: "switch"
        vdom: "<your_own_value> (source system.vdom.name)"
'''
RETURN = '''
build:
  description: Build number of the fortigate image
  returned: always
  type: str
  sample: '1547'
http_method:
  description: Last method used to provision the content into FortiGate
  returned: always
  type: str
  sample: 'PUT'
http_status:
  description: Last result given by FortiGate on last operation applied
  returned: always
  type: str
  sample: "200"
mkey:
  description: Master key (id) used in the last call to FortiGate
  returned: success
  type: str
  sample: "id"
name:
  description: Name of the table used to fulfill the request
  returned: always
  type: str
  sample: "urlfilter"
path:
  description: Path of the table used to fulfill the request
  returned: always
  type: str
  sample: "webfilter"
revision:
  description: Internal revision number
  returned: always
  type: str
  sample: "17.0.2.10658"
serial:
  description: Serial number of the unit
  returned: always
  type: str
  sample: "FGVMEVYYQT3AB5352"
status:
  description: Indication of the operation's result
  returned: always
  type: str
  sample: "success"
vdom:
  description: Virtual domain used
  returned: always
  type: str
  sample: "root"
version:
  description: Version of the FortiGate
  returned: always
  type: str
  sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
    host = data['host']
    username = data['username']
    password = data['password']
    ssl_verify = data['ssl_verify']
    fos.debug('on')
    if 'https' in data and not data['https']:
        fos.https('off')
    else:
        fos.https('on')
    fos.login(host, username, password, verify=ssl_verify)
def filter_system_switch_interface_data(json):
    option_list = ['intra_switch_policy', 'member', 'name',
                   'span', 'span_dest_port', 'span_direction',
                   'span_source_port', 'type', 'vdom']
    dictionary = {}
    for attribute in option_list:
        if attribute in json and json[attribute] is not None:
            dictionary[attribute] = json[attribute]
    return dictionary
def underscore_to_hyphen(data):
    if isinstance(data, list):
        for i, elem in enumerate(data):
            data[i] = underscore_to_hyphen(elem)
    elif isinstance(data, dict):
        new_data = {}
        for k, v in data.items():
            new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
        data = new_data
    return data
def system_switch_interface(data, fos):
    vdom = data['vdom']
    state = data['state']
    system_switch_interface_data = data['system_switch_interface']
    filtered_data = underscore_to_hyphen(filter_system_switch_interface_data(system_switch_interface_data))
    if state == "present":
        return fos.set('system',
                       'switch-interface',
                       data=filtered_data,
                       vdom=vdom)
    elif state == "absent":
        return fos.delete('system',
                          'switch-interface',
                          mkey=filtered_data['name'],
                          vdom=vdom)
def is_successful_status(status):
    return status['status'] == "success" or \
        status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_system(data, fos):
    if data['system_switch_interface']:
        resp = system_switch_interface(data, fos)
    return not is_successful_status(resp), \
        resp['status'] == "success", \
        resp
def main():
    fields = {
        "host": {"required": False, "type": "str"},
        "username": {"required": False, "type": "str"},
        "password": {"required": False, "type": "str", "default": "", "no_log": True},
        "vdom": {"required": False, "type": "str", "default": "root"},
        "https": {"required": False, "type": "bool", "default": True},
        "ssl_verify": {"required": False, "type": "bool", "default": True},
        "state": {"required": True, "type": "str",
                  "choices": ["present", "absent"]},
        "system_switch_interface": {
            "required": False, "type": "dict", "default": None,
            "options": {
                "intra_switch_policy": {"required": False, "type": "str",
                                        "choices": ["implicit", "explicit"]},
                "member": {"required": False, "type": "list",
                           "options": {
                               "interface_name": {"required": False, "type": "str"}
                           }},
                "name": {"required": True, "type": "str"},
                "span": {"required": False, "type": "str",
                         "choices": ["disable", "enable"]},
                "span_dest_port": {"required": False, "type": "str"},
                "span_direction": {"required": False, "type": "str",
                                   "choices": ["rx", "tx", "both"]},
                "span_source_port": {"required": False, "type": "list",
                                     "options": {
                                         "interface_name": {"required": False, "type": "str"}
                                     }},
                "type": {"required": False, "type": "str",
                         "choices": ["switch", "hub"]},


Please complete the code given below. 
/*
 *   
 *
 * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License version 2 for more details (a copy is
 * included at /legal/license.txt).
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions.
 */
package com.sun.cldc.io;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
/**
 * Input stream class for accessing resource files in classpath.
 */
public class ResourceInputStream extends InputStream {
    private Object fileDecoder;
    private Object savedDecoder; // used for mark/reset functionality
    /**
     * Fixes the resource name to be conformant with the CLDC 1.0
     * specification. We are not allowed to use "../" to get outside
     * of the .jar file.
     *
     * @param name the name of the resource in classpath to access.
     * @return     the fixed string.
     * @exception  IOException if the resource name points to a
     *              classfile, as determined by the resource name's
     *              extension.
     */
    private static String fixResourceName(String name) throws IOException {
        Vector dirVector = new Vector();
        int    startIdx = 0;
        int    endIdx = 0;
        String curDir;
        while ((endIdx = name.indexOf('/', startIdx)) != -1) {
            if (endIdx == startIdx) {
                // We have a leading '/' or two consecutive '/'s
                startIdx++;
                continue;
            }
            curDir = name.substring(startIdx, endIdx);
            startIdx = endIdx + 1;
            if (curDir.equals(".")) {
                // Ignore a single '.' directory
                continue;
            }
            if (curDir.equals("..")) {
                // Go up a level
                try {
                    dirVector.removeElementAt(dirVector.size()-1);
                } catch (ArrayIndexOutOfBoundsException aioobe) {
                     // "/../resource" Not allowed!
                     throw new IOException();
                }
                continue;
            }
            dirVector.addElement(curDir);
        }
        // save directory structure
        StringBuffer dirName = new StringBuffer();
        int nelements = dirVector.size();
        for (int i = 0; i < nelements; ++i) {
          dirName.append((String)dirVector.elementAt(i));
          dirName.append("/");
        }
        // save filename
        if (startIdx < name.length()) {
            String filename = name.substring(startIdx);
            // Throw IOE if the resource ends with ".class", but, not
            //  if the entire name is ".class"
            if ((filename.endsWith(".class")) &&
                (! ".class".equals(filename))) {
                throw new IOException();
            }
            dirName.append(name.substring(startIdx));
        }
        return dirName.toString();
    }
    /**
     * Construct a resource input stream for accessing objects in the jar file.
     *
     * @param name the name of the resource in classpath to access. The
     *              name must not have a leading '/'.
     * @exception  IOException  if an I/O error occurs.
     */
    public ResourceInputStream(String name) throws IOException {
        String fixedName = fixResourceName(name);
        fileDecoder = open(fixedName);
        if (fileDecoder == null) {
            throw new IOException();
        }
     }
    /**
     * Reads the next byte of data from the input stream.
     *
     * @return     the next byte of data, or <code>-1</code> if the end
     *             of the stream is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public int read() throws IOException {
        // Fix for CR 6303054
        if (fileDecoder == null) {
            throw new IOException();
        }
        return readByte(fileDecoder);
    }
    /**
     * Gets the number of bytes remaining to be read.
     *
     * @return     the number of bytes remaining in the resource.
     * @exception  IOException  if an I/O error occurs.
     */
    public int available() throws IOException {
        if (fileDecoder == null) {
            throw new IOException();
        }
        return bytesRemain(fileDecoder);
    }
    /**
     * Reads bytes into a byte array.
     *
     * @param b the buffer to read into.
     * @param off offset to start at in the buffer.
     * @param len number of bytes to read.
     * @return     the number of bytes read, or <code>-1</code> if the end
     *             of the stream is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public int read(byte b[], int off, int len) throws IOException {
        // Fix for CR 6303054
        if (fileDecoder == null) {
            throw new IOException();
        }
        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
                   ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        }
        return readBytes(fileDecoder, b, off, len);
    }
    public void close() throws IOException {
        fileDecoder = null;
    }
    /**
     * Remembers current position in ResourceInputStream so that
     * subsequent call to <code>reset</code> will rewind the stream
     * to the saved position.
     *
     * @param readlimit affects nothing
     * @see   java.io.InputStream#reset()
     */
    public void mark(int readlimit) {
        if (fileDecoder != null) {
            savedDecoder = clone(fileDecoder);
        }
    }
    /**
     * Repositions this stream to the position at the time the
     * <code>mark</code> method was last called on this input stream.
     *
     * @exception IOException if this stream has not been marked
     * @see   java.io.InputStream#mark(int)
     */
    public void reset() throws IOException {
        if (fileDecoder == null || savedDecoder == null) {


Please complete the code given below. 
/**
 */
package activitydiagramTrace.States.activitydiagram.impl;
import activitydiagramTrace.States.Activity_trace_Value;
import activitydiagramTrace.States.StatesPackage;
import activitydiagramTrace.States.activitydiagram.ActivitydiagramPackage;
import activitydiagramTrace.States.activitydiagram.TracedActivity;
import java.util.Collection;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.gemoc.activitydiagram.sequential.xactivitydiagram.activitydiagram.Activity;
/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Traced Activity</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link activitydiagramTrace.States.activitydiagram.impl.TracedActivityImpl#getOriginalObject <em>Original Object</em>}</li>
 *   <li>{@link activitydiagramTrace.States.activitydiagram.impl.TracedActivityImpl#getTraceSequence <em>Trace Sequence</em>}</li>
 * </ul>
 *
 * @generated
 */
public class TracedActivityImpl extends TracedNamedElementImpl implements TracedActivity {
	/**
	 * The cached value of the '{@link #getOriginalObject() <em>Original Object</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getOriginalObject()
	 * @generated
	 * @ordered
	 */
	protected Activity originalObject;
	/**
	 * The cached value of the '{@link #getTraceSequence() <em>Trace Sequence</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTraceSequence()
	 * @generated
	 * @ordered
	 */
	protected EList<Activity_trace_Value> traceSequence;
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected TracedActivityImpl() {
		super();
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return ActivitydiagramPackage.Literals.TRACED_ACTIVITY;
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Activity getOriginalObject() {
		if (originalObject != null && originalObject.eIsProxy()) {
			InternalEObject oldOriginalObject = (InternalEObject)originalObject;
			originalObject = (Activity)eResolveProxy(oldOriginalObject);
			if (originalObject != oldOriginalObject) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ActivitydiagramPackage.TRACED_ACTIVITY__ORIGINAL_OBJECT, oldOriginalObject, originalObject));
			}
		}
		return originalObject;
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Activity basicGetOriginalObject() {
		return originalObject;
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setOriginalObject(Activity newOriginalObject) {
		Activity oldOriginalObject = originalObject;
		originalObject = newOriginalObject;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ActivitydiagramPackage.TRACED_ACTIVITY__ORIGINAL_OBJECT, oldOriginalObject, originalObject));
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<Activity_trace_Value> getTraceSequence() {
		if (traceSequence == null) {
			traceSequence = new EObjectContainmentWithInverseEList<Activity_trace_Value>(Activity_trace_Value.class, this, ActivitydiagramPackage.TRACED_ACTIVITY__TRACE_SEQUENCE, StatesPackage.ACTIVITY_TRACE_VALUE__PARENT);
		}
		return traceSequence;
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ActivitydiagramPackage.TRACED_ACTIVITY__TRACE_SEQUENCE:
				return ((InternalEList<InternalEObject>)(InternalEList<?>)getTraceSequence()).basicAdd(otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ActivitydiagramPackage.TRACED_ACTIVITY__TRACE_SEQUENCE:
				return ((InternalEList<?>)getTraceSequence()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case ActivitydiagramPackage.TRACED_ACTIVITY__ORIGINAL_OBJECT:
				if (resolve) return getOriginalObject();
				return basicGetOriginalObject();
			case ActivitydiagramPackage.TRACED_ACTIVITY__TRACE_SEQUENCE:
				return getTraceSequence();
		}
		return super.eGet(featureID, resolve, coreType);
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ActivitydiagramPackage.TRACED_ACTIVITY__ORIGINAL_OBJECT:
				setOriginalObject((Activity)newValue);
				return;
			case ActivitydiagramPackage.TRACED_ACTIVITY__TRACE_SEQUENCE:
				getTraceSequence().clear();
				getTraceSequence().addAll((Collection<? extends Activity_trace_Value>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ActivitydiagramPackage.TRACED_ACTIVITY__ORIGINAL_OBJECT:
				setOriginalObject((Activity)null);
				return;
			case ActivitydiagramPackage.TRACED_ACTIVITY__TRACE_SEQUENCE:
				getTraceSequence().clear();
				return;
		}
		super.eUnset(featureID);
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ActivitydiagramPackage.TRACED_ACTIVITY__ORIGINAL_OBJECT:


Please complete the code given below. 
/*******************************************************************************
 * This file is part of OpenNMS(R).
 *
 * Copyright (C) 2006-2012 The OpenNMS Group, Inc.
 * OpenNMS(R) is Copyright (C) 1999-2012 The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
 *
 * OpenNMS(R) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * OpenNMS(R) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with OpenNMS(R).  If not, see:
 *      http://www.gnu.org/licenses/
 *
 * For more information contact:
 *     OpenNMS(R) Licensing <license@opennms.org>
 *     http://www.opennms.org/
 *     http://www.opennms.com/
 *******************************************************************************/
package org.opennms.netmgt.importer.operations;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.opennms.core.utils.InetAddressUtils;
import org.opennms.netmgt.model.OnmsIpInterface;
import org.opennms.netmgt.model.OnmsMonitoredService;
import org.opennms.netmgt.model.OnmsNode;
import org.opennms.netmgt.model.OnmsServiceType;
import org.opennms.netmgt.model.OnmsSnmpInterface;
import org.opennms.netmgt.xml.event.Event;
/**
 * <p>UpdateOperation class.</p>
 *
 * @author ranger
 * @version $Id: $
 */
public class UpdateOperation extends AbstractSaveOrUpdateOperation {
    
    public class ServiceUpdater {
        
        private OnmsIpInterface m_iface;
        Map<OnmsServiceType, OnmsMonitoredService> m_svcTypToSvcMap;
        public ServiceUpdater(OnmsIpInterface iface, OnmsIpInterface imported) {
            m_iface = iface;
            
            createSvcTypeToSvcMap(imported);
        }
        private void createSvcTypeToSvcMap(OnmsIpInterface imported) {
            m_svcTypToSvcMap = new HashMap<OnmsServiceType, OnmsMonitoredService>();
            for (OnmsMonitoredService svc : imported.getMonitoredServices()) {
                m_svcTypToSvcMap.put(svc.getServiceType(), svc);
            }
        }
        public void execute(List<Event> events) {
            for (Iterator<OnmsMonitoredService> it = getExisting().iterator(); it.hasNext();) {
                OnmsMonitoredService svc = it.next();
                OnmsMonitoredService imported = getImportedVersion(svc);
                if (imported == null) {
                    it.remove();
                    svc.visit(new DeleteEventVisitor(events));
                }
                else {
                    update(svc, events);
                }
                markAsProcessed(svc);
            }
            addNewServices(events);
        }
        private void addNewServices(List<Event> events) {
            Collection<OnmsMonitoredService> newServices = getNewServices();
            log().debug(getNode().getLabel()+" has "+newServices.size()+" new services.");
            for (OnmsMonitoredService svc : newServices) {
                svc.setIpInterface(m_iface);
                m_iface.getMonitoredServices().add(svc);
                svc.visit(new AddEventVisitor(events));
            }
        }
        private Collection<OnmsMonitoredService> getNewServices() {
            return Collections.unmodifiableCollection(m_svcTypToSvcMap.values());
        }
        private void markAsProcessed(OnmsMonitoredService svc) {
            m_svcTypToSvcMap.remove(svc.getServiceType());
        }
        private void update(OnmsMonitoredService svc, List<Event> events) {
            // nothing to do here
        }
        private OnmsMonitoredService getImportedVersion(OnmsMonitoredService svc) {
            return (OnmsMonitoredService)m_svcTypToSvcMap.get(svc.getServiceType());
        }
        Set<OnmsMonitoredService> getExisting() {
            return m_iface.getMonitoredServices();
        }
    }
    public class InterfaceUpdater {
        
        private OnmsNode m_node;
        private Map<String, OnmsIpInterface> m_ipAddrToImportIfs;
        public InterfaceUpdater(OnmsNode node, OnmsNode imported) {
            m_node = node;
            m_ipAddrToImportIfs = getIpAddrToInterfaceMap(imported);
        }
        public void execute(List<Event> events) {
            for (Iterator<OnmsIpInterface> it = getExistingInterfaces().iterator(); it.hasNext();) {
                OnmsIpInterface iface = it.next();
                OnmsIpInterface imported = getImportedVersion(iface);
                
                if (imported == null) {
                    it.remove();
                    iface.visit(new DeleteEventVisitor(events));
                    markAsProcessed(iface);
                } else {
                    update(imported, iface, events);
                    markAsProcessed(iface);
                }
                
            }
            addNewInterfaces(events);
        }
        private void addNewInterfaces(List<Event> events) {
            for (OnmsIpInterface iface : getNewInterfaces()) {
                m_node.addIpInterface(iface);
                if (iface.getIfIndex() != null) {
                    iface.setSnmpInterface(m_node.getSnmpInterfaceWithIfIndex(iface.getIfIndex()));
                }
                iface.visit(new AddEventVisitor(events));
            }
        }
        private OnmsIpInterface getImportedVersion(OnmsIpInterface iface) {
            return m_ipAddrToImportIfs.get(InetAddressUtils.str(iface.getIpAddress()));
        }
        private Collection<OnmsIpInterface> getNewInterfaces() {
            return m_ipAddrToImportIfs.values();
        }
        private void markAsProcessed(OnmsIpInterface iface) {
            m_ipAddrToImportIfs.remove(InetAddressUtils.str(iface.getIpAddress()));
        }
        private void update(OnmsIpInterface imported, OnmsIpInterface iface, List<Event> events) {
            if (!nullSafeEquals(iface.getIsManaged(), imported.getIsManaged()))
                iface.setIsManaged(imported.getIsManaged());
            
            if (!nullSafeEquals(iface.getIsSnmpPrimary(), imported.getIsSnmpPrimary())) {
                iface.setIsSnmpPrimary(imported.getIsSnmpPrimary());
                // TODO: send snmpPrimary event
            }
            
            if (isSnmpDataForInterfacesUpToDate()) {
            	updateSnmpInterface(imported, iface);
            }
            
           if (!nullSafeEquals(iface.getIpHostName(), imported.getIpHostName()))
        	   iface.setIpHostName(imported.getIpHostName());
           
           updateServices(iface, imported, events);
        }
		private void updateSnmpInterface(OnmsIpInterface imported, OnmsIpInterface iface) {
			if (nullSafeEquals(iface.getIfIndex(), imported.getIfIndex())) {
                // no need to change anything
                return;
            }
            
            if (imported.getSnmpInterface() == null) {
                // there is no longer an snmpInterface associated with the ipInterface
                iface.setSnmpInterface(null);
            } else {
                // locate the snmpInterface on this node that has the new ifIndex and set it
                // into the interface
                OnmsSnmpInterface snmpIface = m_node.getSnmpInterfaceWithIfIndex(imported.getIfIndex());
                iface.setSnmpInterface(snmpIface);
            }
            
            
            
		}
        
        private void updateServices(OnmsIpInterface iface, OnmsIpInterface imported, List<Event> events) {
            new ServiceUpdater(iface, imported).execute(events);
        }
        private Set<OnmsIpInterface> getExistingInterfaces() {
            return m_node.getIpInterfaces();
        }
    }
    
    public class SnmpInterfaceUpdater {
        
        OnmsNode m_dbNode;
        Map<Integer, OnmsSnmpInterface> m_ifIndexToSnmpInterface;
        public SnmpInterfaceUpdater(OnmsNode db, OnmsNode imported) {
            m_dbNode = db;
            m_ifIndexToSnmpInterface = mapIfIndexToSnmpInterface(imported.getSnmpInterfaces());
        }
        private Map<Integer, OnmsSnmpInterface> mapIfIndexToSnmpInterface(Set<OnmsSnmpInterface> snmpInterfaces) {
            Map<Integer, OnmsSnmpInterface> map = new HashMap<Integer, OnmsSnmpInterface>();
            for (OnmsSnmpInterface snmpIface : snmpInterfaces) {
                if (snmpIface.getIfIndex() != null) {
                    map.put(snmpIface.getIfIndex(), snmpIface);
                }
            }
            return map;
        }
        public void execute() {
            for (Iterator<OnmsSnmpInterface> it = getExistingInterfaces().iterator(); it.hasNext();) {
                OnmsSnmpInterface iface = (OnmsSnmpInterface) it.next();
                OnmsSnmpInterface imported = getImportedVersion(iface);
                if (imported == null) {
                    it.remove();
                    markAsProcessed(iface);
                } else {
                    update(imported, iface);
                    markAsProcessed(iface);
                }
            }
            addNewInterfaces();
        }
        
        private void update(OnmsSnmpInterface importedSnmpIface, OnmsSnmpInterface snmpIface) {
            
            if (!nullSafeEquals(snmpIface.getIfAdminStatus(), importedSnmpIface.getIfAdminStatus())) {
                snmpIface.setIfAdminStatus(importedSnmpIface.getIfAdminStatus());
            }
            
            if (!nullSafeEquals(snmpIface.getIfAlias(), importedSnmpIface.getIfAlias())) {
                snmpIface.setIfAlias(importedSnmpIface.getIfAlias());
            }
            
            if (!nullSafeEquals(snmpIface.getIfDescr(), importedSnmpIface.getIfDescr())) {
                snmpIface.setIfDescr(importedSnmpIface.getIfDescr());
            }
                
            if (!nullSafeEquals(snmpIface.getIfName(), importedSnmpIface.getIfName())) {
                snmpIface.setIfName(importedSnmpIface.getIfName());
            }
            
            if (!nullSafeEquals(snmpIface.getIfOperStatus(), importedSnmpIface.getIfOperStatus())) {
                snmpIface.setIfOperStatus(importedSnmpIface.getIfOperStatus());
            }
            
            if (!nullSafeEquals(snmpIface.getIfSpeed(), importedSnmpIface.getIfSpeed())) {
                snmpIface.setIfSpeed(importedSnmpIface.getIfSpeed());
            }
            
            if (!nullSafeEquals(snmpIface.getIfType(), importedSnmpIface.getIfType())) {
                snmpIface.setIfType(importedSnmpIface.getIfType());
            }
            
            if (!nullSafeEquals(snmpIface.getNetMask(), importedSnmpIface.getNetMask())) {
                snmpIface.setNetMask(importedSnmpIface.getNetMask());
            }
            
            if (!nullSafeEquals(snmpIface.getPhysAddr(), importedSnmpIface.getPhysAddr())) {
                snmpIface.setPhysAddr(importedSnmpIface.getPhysAddr());
            }
            
        }
        private void markAsProcessed(OnmsSnmpInterface iface) {
            m_ifIndexToSnmpInterface.remove(iface.getIfIndex());
        }
        private OnmsSnmpInterface getImportedVersion(OnmsSnmpInterface iface) {
            return m_ifIndexToSnmpInterface.get(iface.getIfIndex());
        }
        private Set<OnmsSnmpInterface> getExistingInterfaces() {
            return m_dbNode.getSnmpInterfaces();
       }
        
        private void addNewInterfaces() {
            for (OnmsSnmpInterface snmpIface : getNewInterfaces()) {
                m_dbNode.addSnmpInterface(snmpIface);
            }
        }
        private Collection<OnmsSnmpInterface> getNewInterfaces() {
            return m_ifIndexToSnmpInterface.values();
        }
    }
    /**
     * <p>Constructor for UpdateOperation.</p>
     *
     * @param nodeId a {@link java.lang.Integer} object.
     * @param foreignSource a {@link java.lang.String} object.
     * @param foreignId a {@link java.lang.String} object.
     * @param nodeLabel a {@link java.lang.String} object.
     * @param building a {@link java.lang.String} object.
     * @param city a {@link java.lang.String} object.
     */
    public UpdateOperation(Integer nodeId, String foreignSource, String foreignId, String nodeLabel, String building, String city) {
		super(nodeId, foreignSource, foreignId, nodeLabel, building, city);
	}
	/**
	 * <p>doPersist</p>
	 *
	 * @return a {@link java.util.List} object.
	 */
	public List<Event> doPersist() {
		OnmsNode imported = getNode();
		OnmsNode db = getNodeDao().getHierarchy(imported.getId());


Please complete the code given below. 
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Loic Blot (@nerzhul) <loic.blot@unix-experience.fr>
# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) <aaklychkov@mail.ru>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
                    'status': ['preview'],
                    'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: postgresql_publication
short_description: Add, update, or remove PostgreSQL publication
description:
- Add, update, or remove PostgreSQL publication.
version_added: "2.9"
options:
  name:
    description:
    - Name of the publication to add, update, or remove.
    required: true
    type: str
  db:
    description:
    - Name of the database to connect to and where
      the publication state will be changed.
    aliases: [ login_db ]
    type: str
  tables:
    description:
    - List of tables to add to the publication.
    - If no value is set all tables are targeted.
    - If the publication already exists for specific tables and I(tables) is not passed,
      nothing will be changed. If you need to add all tables to the publication with the same name,
      drop existent and create new without passing I(tables).
    type: list
  state:
    description:
    - The publication state.
    default: present
    choices: [ absent, present ]
    type: str
  parameters:
    description:
    - Dictionary with optional publication parameters.
    - Available parameters depend on PostgreSQL version.
    type: dict
  owner:
    description:
    - Publication owner.
    - If I(owner) is not defined, the owner will be set as I(login_user) or I(session_role).
    type: str
  cascade:
    description:
    - Drop publication dependencies. Has effect with I(state=absent) only.
    type: bool
    default: false
notes:
- PostgreSQL version must be 10 or greater.
seealso:
- name: CREATE PUBLICATION reference
  description: Complete reference of the CREATE PUBLICATION command documentation.
  link: https://www.postgresql.org/docs/current/sql-createpublication.html
- name: ALTER PUBLICATION reference
  description: Complete reference of the ALTER PUBLICATION command documentation.
  link: https://www.postgresql.org/docs/current/sql-alterpublication.html
- name: DROP PUBLICATION reference
  description: Complete reference of the DROP PUBLICATION command documentation.
  link: https://www.postgresql.org/docs/current/sql-droppublication.html
author:
- Loic Blot (@nerzhul) <loic.blot@unix-experience.fr>
- Andrew Klychkov (@Andersson007) <aaklychkov@mail.ru>
extends_documentation_fragment:
- postgres
'''
EXAMPLES = r'''
- name: Create a new publication with name "acme" targeting all tables in database "test".
  postgresql_publication:
    db: test
    name: acme
- name: Create publication "acme" publishing only prices and vehicles tables.
  postgresql_publication:
    name: acme
    tables:
    - prices
    - vehicles
- name: >
    Create publication "acme", set user alice as an owner, targeting all tables.
    Allowable DML operations are INSERT and UPDATE only
  postgresql_publication:
    name: acme
    owner: alice
    parameters:
      publish: 'insert,update'
- name: >
    Assuming publication "acme" exists and there are targeted
    tables "prices" and "vehicles", add table "stores" to the publication.
  postgresql_publication:
    name: acme
    tables:
    - prices
    - vehicles
    - stores
- name: Remove publication "acme" if exists in database "test".
  postgresql_publication:
    db: test
    name: acme
    state: absent
'''
RETURN = r'''
exists:
  description:
  - Flag indicates the publication exists or not at the end of runtime.
  returned: always
  type: bool
  sample: true
queries:
  description: List of executed queries.
  returned: always
  type: str
  sample: [ 'DROP PUBLICATION "acme" CASCADE' ]
owner:
  description: Owner of the publication at the end of runtime.
  returned: if publication exists
  type: str
  sample: "alice"
tables:
  description:
  - List of tables in the publication at the end of runtime.
  - If all tables are published, returns empty list.
  returned: if publication exists
  type: list
  sample: ["\"public\".\"prices\"", "\"public\".\"vehicles\""]
alltables:
  description:
  - Flag indicates that all tables are published.
  returned: if publication exists
  type: bool
  sample: false
parameters:
  description: Publication parameters at the end of runtime.
  returned: if publication exists
  type: dict
  sample: {'publish': {'insert': false, 'delete': false, 'update': true}}
'''
try:
    from psycopg2.extras import DictCursor
except ImportError:
    # psycopg2 is checked by connect_to_db()
    # from ansible.module_utils.postgres
    pass
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.database import pg_quote_identifier
from ansible.module_utils.postgres import (
    connect_to_db,
    exec_sql,
    get_conn_params,
    postgres_common_argument_spec,
)
from ansible.module_utils.six import iteritems
SUPPORTED_PG_VERSION = 10000
################################
# Module functions and classes #
################################
def transform_tables_representation(tbl_list):
    """Add 'public.' to names of tables where a schema identifier is absent
    and add quotes to each element.
    Args:
        tbl_list (list): List of table names.
    Returns:
        tbl_list (list): Changed list.
    """
    for i, table in enumerate(tbl_list):
        if '.' not in table:
            tbl_list[i] = pg_quote_identifier('public.%s' % table.strip(), 'table')
        else:
            tbl_list[i] = pg_quote_identifier(table.strip(), 'table')
    return tbl_list
class PgPublication():
    """Class to work with PostgreSQL publication.
    Args:
        module (AnsibleModule): Object of AnsibleModule class.
        cursor (cursor): Cursor object of psycopg2 library to work with PostgreSQL.
        name (str): The name of the publication.
    Attributes:
        module (AnsibleModule): Object of AnsibleModule class.
        cursor (cursor): Cursor object of psycopg2 library to work with PostgreSQL.
        name (str): Name of the publication.
        executed_queries (list): List of executed queries.
        attrs (dict): Dict with publication attributes.
        exists (bool): Flag indicates the publication exists or not.
    """
    def __init__(self, module, cursor, name):
        self.module = module
        self.cursor = cursor
        self.name = name
        self.executed_queries = []
        self.attrs = {
            'alltables': False,
            'tables': [],
            'parameters': {},
            'owner': '',
        }
        self.exists = self.check_pub()
    def get_info(self):
        """Refresh the publication information.
        Returns:
            ``self.attrs``.
        """
        self.exists = self.check_pub()
        return self.attrs
    def check_pub(self):
        """Check the publication and refresh ``self.attrs`` publication attribute.
        Returns:
            True if the publication with ``self.name`` exists, False otherwise.
        """
        pub_info = self.__get_general_pub_info()
        if not pub_info:
            # Publication does not exist:
            return False
        self.attrs['owner'] = pub_info.get('pubowner')
        # Publication DML operations:
        self.attrs['parameters']['publish'] = {}
        self.attrs['parameters']['publish']['insert'] = pub_info.get('pubinsert', False)
        self.attrs['parameters']['publish']['update'] = pub_info.get('pubupdate', False)
        self.attrs['parameters']['publish']['delete'] = pub_info.get('pubdelete', False)
        if pub_info.get('pubtruncate'):
            self.attrs['parameters']['publish']['truncate'] = pub_info.get('pubtruncate')
        # If alltables flag is False, get the list of targeted tables:
        if not pub_info.get('puballtables'):
            table_info = self.__get_tables_pub_info()
            # Join sublists [['schema', 'table'], ...] to ['schema.table', ...]
            # for better representation:
            for i, schema_and_table in enumerate(table_info):
                table_info[i] = pg_quote_identifier('.'.join(schema_and_table), 'table')
            self.attrs['tables'] = table_info
        else:
            self.attrs['alltables'] = True
        # Publication exists:
        return True
    def create(self, tables, params, owner, check_mode=True):
        """Create the publication.
        Args:
            tables (list): List with names of the tables that need to be added to the publication.
            params (dict): Dict contains optional publication parameters and their values.
            owner (str): Name of the publication owner.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            changed (bool): True if publication has been created, otherwise False.
        """
        changed = True
        query_fragments = ["CREATE PUBLICATION %s" % pg_quote_identifier(self.name, 'publication')]
        if tables:
            query_fragments.append("FOR TABLE %s" % ', '.join(tables))
        else:
            query_fragments.append("FOR ALL TABLES")
        if params:
            params_list = []
            # Make list ["param = 'value'", ...] from params dict:
            for (key, val) in iteritems(params):
                params_list.append("%s = '%s'" % (key, val))
            # Add the list to query_fragments:
            query_fragments.append("WITH (%s)" % ', '.join(params_list))
        changed = self.__exec_sql(' '.join(query_fragments), check_mode=check_mode)
        if owner:
            # If check_mode, just add possible SQL to
            # executed_queries and return:
            self.__pub_set_owner(owner, check_mode=check_mode)
        return changed
    def update(self, tables, params, owner, check_mode=True):
        """Update the publication.
        Args:
            tables (list): List with names of the tables that need to be presented in the publication.
            params (dict): Dict contains optional publication parameters and their values.
            owner (str): Name of the publication owner.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            changed (bool): True if publication has been updated, otherwise False.
        """
        changed = False
        # Add or drop tables from published tables suit:
        if tables and not self.attrs['alltables']:
            # 1. If needs to add table to the publication:
            for tbl in tables:
                if tbl not in self.attrs['tables']:
                    # If needs to add table to the publication:
                    changed = self.__pub_add_table(tbl, check_mode=check_mode)
            # 2. if there is a table in targeted tables
            # that's not presented in the passed tables:
            for tbl in self.attrs['tables']:
                if tbl not in tables:
                    changed = self.__pub_drop_table(tbl, check_mode=check_mode)
        elif tables and self.attrs['alltables']:
            changed = self.__pub_set_tables(tables, check_mode=check_mode)
        # Update pub parameters:
        if params:
            for key, val in iteritems(params):
                if self.attrs['parameters'].get(key):
                    # In PostgreSQL 10/11 only 'publish' optional parameter is presented.
                    if key == 'publish':
                        # 'publish' value can be only a string with comma-separated items
                        # of allowed DML operations like 'insert,update' or
                        # 'insert,update,delete', etc.
                        # Make dictionary to compare with current attrs later:
                        val_dict = self.attrs['parameters']['publish'].copy()
                        val_list = val.split(',')
                        for v in val_dict:
                            if v in val_list:
                                val_dict[v] = True
                            else:
                                val_dict[v] = False
                        # Compare val_dict and the dict with current 'publish' parameters,
                        # if they're different, set new values:
                        if val_dict != self.attrs['parameters']['publish']:
                            changed = self.__pub_set_param(key, val, check_mode=check_mode)
                    # Default behavior for other cases:
                    elif self.attrs['parameters'][key] != val:
                        changed = self.__pub_set_param(key, val, check_mode=check_mode)
                else:
                    # If the parameter was not set before:
                    changed = self.__pub_set_param(key, val, check_mode=check_mode)
        # Update pub owner:
        if owner:
            if owner != self.attrs['owner']:
                changed = self.__pub_set_owner(owner, check_mode=check_mode)
        return changed
    def drop(self, cascade=False, check_mode=True):
        """Drop the publication.
        Kwargs:
            cascade (bool): Flag indicates that publication needs to be deleted
                with its dependencies.
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            changed (bool): True if publication has been updated, otherwise False.
        """
        if self.exists:
            query_fragments = []
            query_fragments.append("DROP PUBLICATION %s" % pg_quote_identifier(self.name, 'publication'))
            if cascade:
                query_fragments.append("CASCADE")
            return self.__exec_sql(' '.join(query_fragments), check_mode=check_mode)
    def __get_general_pub_info(self):
        """Get and return general publication information.
        Returns:
            Dict with publication information if successful, False otherwise.
        """
        # Check pg_publication.pubtruncate exists (supported from PostgreSQL 11):
        pgtrunc_sup = exec_sql(self, ("SELECT 1 FROM information_schema.columns "
                                      "WHERE table_name = 'pg_publication' "
                                      "AND column_name = 'pubtruncate'"), add_to_executed=False)
        if pgtrunc_sup:
            query = ("SELECT r.rolname AS pubowner, p.puballtables, p.pubinsert, "
                     "p.pubupdate , p.pubdelete, p.pubtruncate FROM pg_publication AS p "
                     "JOIN pg_catalog.pg_roles AS r "
                     "ON p.pubowner = r.oid "
                     "WHERE p.pubname = '%s'" % self.name)
        else:
            query = ("SELECT r.rolname AS pubowner, p.puballtables, p.pubinsert, "
                     "p.pubupdate , p.pubdelete FROM pg_publication AS p "
                     "JOIN pg_catalog.pg_roles AS r "
                     "ON p.pubowner = r.oid "
                     "WHERE p.pubname = '%s'" % self.name)
        result = exec_sql(self, query, add_to_executed=False)
        if result:
            return result[0]
        else:
            return False
    def __get_tables_pub_info(self):
        """Get and return tables that are published by the publication.
        Returns:
            List of dicts with published tables.
        """
        query = ("SELECT schemaname, tablename "
                 "FROM pg_publication_tables WHERE pubname = '%s'" % self.name)
        return exec_sql(self, query, add_to_executed=False)
    def __pub_add_table(self, table, check_mode=False):
        """Add a table to the publication.
        Args:
            table (str): Table name.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            True if successful, False otherwise.
        """
        query = ("ALTER PUBLICATION %s ADD TABLE %s" % (pg_quote_identifier(self.name, 'publication'),
                                                        pg_quote_identifier(table, 'table')))
        return self.__exec_sql(query, check_mode=check_mode)
    def __pub_drop_table(self, table, check_mode=False):
        """Drop a table from the publication.
        Args:
            table (str): Table name.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            True if successful, False otherwise.
        """
        query = ("ALTER PUBLICATION %s DROP TABLE %s" % (pg_quote_identifier(self.name, 'publication'),
                                                         pg_quote_identifier(table, 'table')))
        return self.__exec_sql(query, check_mode=check_mode)
    def __pub_set_tables(self, tables, check_mode=False):
        """Set a table suit that need to be published by the publication.
        Args:
            tables (list): List of tables.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            True if successful, False otherwise.
        """
        quoted_tables = [pg_quote_identifier(t, 'table') for t in tables]
        query = ("ALTER PUBLICATION %s SET TABLE %s" % (pg_quote_identifier(self.name, 'publication'),
                                                        ', '.join(quoted_tables)))
        return self.__exec_sql(query, check_mode=check_mode)
    def __pub_set_param(self, param, value, check_mode=False):
        """Set an optional publication parameter.
        Args:
            param (str): Name of the parameter.
            value (str): Parameter value.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            True if successful, False otherwise.
        """
        query = ("ALTER PUBLICATION %s SET (%s = '%s')" % (pg_quote_identifier(self.name, 'publication'),
                                                           param, value))
        return self.__exec_sql(query, check_mode=check_mode)
    def __pub_set_owner(self, role, check_mode=False):
        """Set a publication owner.
        Args:
            role (str): Role (user) name that needs to be set as a publication owner.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just make SQL, add it to ``self.executed_queries`` and return True.
        Returns:
            True if successful, False otherwise.
        """
        query = ("ALTER PUBLICATION %s OWNER TO %s" % (pg_quote_identifier(self.name, 'publication'),
                                                       pg_quote_identifier(role, 'role')))
        return self.__exec_sql(query, check_mode=check_mode)
    def __exec_sql(self, query, check_mode=False):
        """Execute SQL query.
        Note: If we need just to get information from the database,
            we use ``exec_sql`` function directly.
        Args:
            query (str): Query that needs to be executed.
        Kwargs:
            check_mode (bool): If True, don't actually change anything,
                just add ``query`` to ``self.executed_queries`` and return True.
        Returns:
            True if successful, False otherwise.
        """
        if check_mode:
            self.executed_queries.append(query)
            return True
        else:
            return exec_sql(self, query, ddl=True)
# ===========================================
# Module execution.
#
def main():
    argument_spec = postgres_common_argument_spec()
    argument_spec.update(
        name=dict(required=True),
        db=dict(type='str', aliases=['login_db']),
        state=dict(type='str', default='present', choices=['absent', 'present']),
        tables=dict(type='list'),
        parameters=dict(type='dict'),
        owner=dict(type='str'),
        cascade=dict(type='bool', default=False),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
    )
    # Parameters handling:
    name = module.params['name']
    state = module.params['state']
    tables = module.params['tables']
    params = module.params['parameters']
    owner = module.params['owner']
    cascade = module.params['cascade']
    if state == 'absent':
        if tables:
            module.warn('parameter "tables" is ignored when "state=absent"')
        if params:
            module.warn('parameter "parameters" is ignored when "state=absent"')
        if owner:
            module.warn('parameter "owner" is ignored when "state=absent"')
    if state == 'present' and cascade:
        module.warm('parameter "cascade" is ignored when "state=present"')
    # Connect to DB and make cursor object:
    conn_params = get_conn_params(module, module.params)
    # We check publication state without DML queries execution, so set autocommit:
    db_connection = connect_to_db(module, conn_params, autocommit=True)
    cursor = db_connection.cursor(cursor_factory=DictCursor)
    # Check version:
    if cursor.connection.server_version < SUPPORTED_PG_VERSION:
        module.fail_json(msg="PostgreSQL server version should be 10.0 or greater")
    # Nothing was changed by default:
    changed = False
    ###################################
    # Create object and do rock'n'roll:
    publication = PgPublication(module, cursor, name)
    if tables:
        tables = transform_tables_representation(tables)
    # If module.check_mode=True, nothing will be changed:


Please complete the code given below. 
/////////////////////////////////////////////////////
//
//Created by:  Morrigan and Ashlar, together forever.
//
/////////////////////////////////////////////////////
using System;
using Server;
using Server.Items;
namespace Server.Items
{
	public class NujelmHoneySmallFishtankAddon : BaseAddon
	{
		public override BaseAddonDeed Deed
		{
			get
			{
				return new NujelmHoneySmallFishtankAddonDeed();
			}
		}
		[ Constructable ]
		public NujelmHoneySmallFishtankAddon()
		{
			AddonComponent ac = null;
/////////////////////////////////////////////////////////////////////////////////////////
/*Example		
			Variable ac= new item "AddonComponet" with a item id of (dec number - not hex)
			ac 	     = new AddonComponent				( 5990 );
			the new item has a hue of 1 (index number)
			ac.Hue = 1;
			the new item is located at the ( targeted location, x(n -s), y(e -w), z(u-d)
			AddComponent			 ( ac, 		    0, 	 0, 	    0 );
*/
////////////////////////////////////////////////////////////////////////////////////////
//Tank
			//Black on bottom of tank
			ac = new AddonComponent( 5990 );
			ac.Hue = 1;
			ac.Name = "fishtank base";
			AddComponent( ac, 0, 0, 0 );
			ac = new AddonComponent( 5992 );
			ac.Hue = 1;
			ac.Name = "fishtank base";
			AddComponent( ac, 0, 0, 0 );
			ac = new AddonComponent( 5990 );
			ac.Hue = 1;
			ac.Name = "fishtank base";
			AddComponent( ac, 0, 0, 1 );
			ac = new AddonComponent( 5992 );
			ac.Hue = 1;
			ac.Name = "fishtank base";
			AddComponent( ac, 0, 0, 1 );
			//Shades of blue
			ac = new AddonComponent( 5990 );
			ac.Hue = 92;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 2 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 92;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 2 );
			ac = new AddonComponent( 5990 );
			ac.Hue = 92;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 3 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 92;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 3 );
			ac = new AddonComponent( 5990 );
			ac.Hue = 93;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 4 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 93;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 4 );
			ac = new AddonComponent( 5990 );
			ac.Hue = 93;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 5 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 93;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 5 );
			ac = new AddonComponent( 5990 );
			ac.Hue = 94;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 6 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 94;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 6 );
			ac = new AddonComponent( 5990 );
			ac.Hue = 94;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 7 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 94;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 7 );
			ac = new AddonComponent( 5990 );
			ac.Hue = 95;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 8 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 95;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 8 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 95;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 9 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 95;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 9 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 96;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 10 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 96;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 10 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 96;
			ac.Name = "water";
			AddComponent( ac, 0, 0, 11 );
			//Black on top of tank
			ac = new AddonComponent( 4846 );
			ac.Hue = 1;
			ac.Name = "fishtank lid";
			AddComponent( ac, 0, 0, 13 );
			ac = new AddonComponent( 4846 );
			ac.Hue = 1;
			ac.Name = "fishtank lid";
			AddComponent( ac, 0, 0, 14 );
			//Sand
			ac = new AddonComponent( 4846 );
			ac.Hue = 348;
			ac.Name = "sand";
			AddComponent( ac, 1, 1, 12 );
			//Plant and fish
			ac = new AddonComponent( 15110 );
			ac.Name = "a Nujelm Honey";
			AddComponent( ac, 1, 1, 16 );
		}
		public NujelmHoneySmallFishtankAddon( Serial serial ) : base( serial )
		{
		}
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( 0 ); // Version
		}
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();
		}
	}
	public class NujelmHoneySmallFishtankAddonDeed : BaseAddonDeed
	{
		public override BaseAddon Addon
		{
			get
			{
				return new NujelmHoneySmallFishtankAddon();
			}
		}
		[Constructable]
		public NujelmHoneySmallFishtankAddonDeed()
		{
			Name = "a Nujelm Honey small fishtank";
		}
		public NujelmHoneySmallFishtankAddonDeed( Serial serial ) : base( serial )
		{
		}
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( 0 ); // Version
		}
		public override void	Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );


Please complete the code given below. 
"""This tutorial introduces restricted boltzmann machines (RBM) using Theano.
Boltzmann Machines (BMs) are a particular form of energy-based model which
contain hidden variables. Restricted Boltzmann Machines further restrict BMs
to those without visible-visible and hidden-hidden connections.
"""
import timeit
try:
    import PIL.Image as Image
except ImportError:
    import Image
import numpy
import theano
import theano.tensor as T
import os
from theano.tensor.shared_randomstreams import RandomStreams
from utils import tile_raster_images
from logistic_sgd import load_data
# start-snippet-1
class RBM(object):
    """Restricted Boltzmann Machine (RBM)  """
    def __init__(
        self,
        input=None,
        n_visible=784,
        n_hidden=500,
        W=None,
        hbias=None,
        vbias=None,
        numpy_rng=None,
        theano_rng=None
    ):
        """
        RBM constructor. Defines the parameters of the model along with
        basic operations for inferring hidden from visible (and vice-versa),
        as well as for performing CD updates.
        :param input: None for standalone RBMs or symbolic variable if RBM is
        part of a larger graph.
        :param n_visible: number of visible units
        :param n_hidden: number of hidden units
        :param W: None for standalone RBMs or symbolic variable pointing to a
        shared weight matrix in case RBM is part of a DBN network; in a DBN,
        the weights are shared between RBMs and layers of a MLP
        :param hbias: None for standalone RBMs or symbolic variable pointing
        to a shared hidden units bias vector in case RBM is part of a
        different network
        :param vbias: None for standalone RBMs or a symbolic variable
        pointing to a shared visible units bias
        """
        self.n_visible = n_visible
        self.n_hidden = n_hidden
        if numpy_rng is None:
            # create a number generator
            numpy_rng = numpy.random.RandomState(1234)
        if theano_rng is None:
            theano_rng = RandomStreams(numpy_rng.randint(2 ** 30))
        if W is None:
            # W is initialized with `initial_W` which is uniformely
            # sampled from -4*sqrt(6./(n_visible+n_hidden)) and
            # 4*sqrt(6./(n_hidden+n_visible)) the output of uniform if
            # converted using asarray to dtype theano.config.floatX so
            # that the code is runable on GPU
            initial_W = numpy.asarray(
                numpy_rng.uniform(
                    low=-4 * numpy.sqrt(6. / (n_hidden + n_visible)),
                    high=4 * numpy.sqrt(6. / (n_hidden + n_visible)),
                    size=(n_visible, n_hidden)
                ),
                dtype=theano.config.floatX
            )
            # theano shared variables for weights and biases
            W = theano.shared(value=initial_W, name='W', borrow=True)
        if hbias is None:
            # create shared variable for hidden units bias
            hbias = theano.shared(
                value=numpy.zeros(
                    n_hidden,
                    dtype=theano.config.floatX
                ),
                name='hbias',
                borrow=True
            )
        if vbias is None:
            # create shared variable for visible units bias
            vbias = theano.shared(
                value=numpy.zeros(
                    n_visible,
                    dtype=theano.config.floatX
                ),
                name='vbias',
                borrow=True
            )
        # initialize input layer for standalone RBM or layer0 of DBN
        self.input = input
        if not input:
            self.input = T.matrix('input')
        self.W = W
        self.hbias = hbias
        self.vbias = vbias
        self.theano_rng = theano_rng
        # **** WARNING: It is not a good idea to put things in this list
        # other than shared variables created in this function.
        self.params = [self.W, self.hbias, self.vbias]
        # end-snippet-1
    def free_energy(self, v_sample):
        ''' Function to compute the free energy '''
        wx_b = T.dot(v_sample, self.W) + self.hbias
        vbias_term = T.dot(v_sample, self.vbias)
        hidden_term = T.sum(T.log(1 + T.exp(wx_b)), axis=1)
        return -hidden_term - vbias_term
    def propup(self, vis):
        '''This function propagates the visible units activation upwards to
        the hidden units
        Note that we return also the pre-sigmoid activation of the
        layer. As it will turn out later, due to how Theano deals with
        optimizations, this symbolic variable will be needed to write
        down a more stable computational graph (see details in the
        reconstruction cost function)
        '''
        pre_sigmoid_activation = T.dot(vis, self.W) + self.hbias
        return [pre_sigmoid_activation, T.nnet.sigmoid(pre_sigmoid_activation)]
    def sample_h_given_v(self, v0_sample):
        ''' This function infers state of hidden units given visible units '''
        # compute the activation of the hidden units given a sample of
        # the visibles
        pre_sigmoid_h1, h1_mean = self.propup(v0_sample)
        # get a sample of the hiddens given their activation
        # Note that theano_rng.binomial returns a symbolic sample of dtype
        # int64 by default. If we want to keep our computations in floatX
        # for the GPU we need to specify to return the dtype floatX
        h1_sample = self.theano_rng.binomial(size=h1_mean.shape,
                                             n=1, p=h1_mean,
                                             dtype=theano.config.floatX)
        return [pre_sigmoid_h1, h1_mean, h1_sample]
    def propdown(self, hid):
        '''This function propagates the hidden units activation downwards to
        the visible units
        Note that we return also the pre_sigmoid_activation of the
        layer. As it will turn out later, due to how Theano deals with
        optimizations, this symbolic variable will be needed to write
        down a more stable computational graph (see details in the
        reconstruction cost function)
        '''
        pre_sigmoid_activation = T.dot(hid, self.W.T) + self.vbias
        return [pre_sigmoid_activation, T.nnet.sigmoid(pre_sigmoid_activation)]
    def sample_v_given_h(self, h0_sample):
        ''' This function infers state of visible units given hidden units '''
        # compute the activation of the visible given the hidden sample
        pre_sigmoid_v1, v1_mean = self.propdown(h0_sample)
        # get a sample of the visible given their activation
        # Note that theano_rng.binomial returns a symbolic sample of dtype
        # int64 by default. If we want to keep our computations in floatX
        # for the GPU we need to specify to return the dtype floatX
        v1_sample = self.theano_rng.binomial(size=v1_mean.shape,
                                             n=1, p=v1_mean,
                                             dtype=theano.config.floatX)
        return [pre_sigmoid_v1, v1_mean, v1_sample]
    def gibbs_hvh(self, h0_sample):
        ''' This function implements one step of Gibbs sampling,
            starting from the hidden state'''
        pre_sigmoid_v1, v1_mean, v1_sample = self.sample_v_given_h(h0_sample)
        pre_sigmoid_h1, h1_mean, h1_sample = self.sample_h_given_v(v1_sample)
        return [pre_sigmoid_v1, v1_mean, v1_sample,
                pre_sigmoid_h1, h1_mean, h1_sample]
    def gibbs_vhv(self, v0_sample):
        ''' This function implements one step of Gibbs sampling,
            starting from the visible state'''
        pre_sigmoid_h1, h1_mean, h1_sample = self.sample_h_given_v(v0_sample)
        pre_sigmoid_v1, v1_mean, v1_sample = self.sample_v_given_h(h1_sample)
        return [pre_sigmoid_h1, h1_mean, h1_sample,
                pre_sigmoid_v1, v1_mean, v1_sample]
    # start-snippet-2
    def get_cost_updates(self, lr=0.1, persistent=None, k=1):
        """This functions implements one step of CD-k or PCD-k
        :param lr: learning rate used to train the RBM
        :param persistent: None for CD. For PCD, shared variable
            containing old state of Gibbs chain. This must be a shared
            variable of size (batch size, number of hidden units).
        :param k: number of Gibbs steps to do in CD-k/PCD-k
        Returns a proxy for the cost and the updates dictionary. The
        dictionary contains the update rules for weights and biases but
        also an update of the shared variable used to store the persistent
        chain, if one is used.
        """
        # compute positive phase
        pre_sigmoid_ph, ph_mean, ph_sample = self.sample_h_given_v(self.input)
        # decide how to initialize persistent chain:
        # for CD, we use the newly generate hidden sample
        # for PCD, we initialize from the old state of the chain
        if persistent is None:
            chain_start = ph_sample
        else:
            chain_start = persistent
        # end-snippet-2
        # perform actual negative phase
        # in order to implement CD-k/PCD-k we need to scan over the
        # function that implements one gibbs step k times.
        # Read Theano tutorial on scan for more information :
        # http://deeplearning.net/software/theano/library/scan.html
        # the scan will return the entire Gibbs chain
        (
            [
                pre_sigmoid_nvs,
                nv_means,
                nv_samples,
                pre_sigmoid_nhs,
                nh_means,
                nh_samples
            ],
            updates
        ) = theano.scan(
            self.gibbs_hvh,
            # the None are place holders, saying that
            # chain_start is the initial state corresponding to the
            # 6th output
            outputs_info=[None, None, None, None, None, chain_start],
            n_steps=k
        )
        # start-snippet-3
        # determine gradients on RBM parameters
        # note that we only need the sample at the end of the chain
        chain_end = nv_samples[-1]
        cost = T.mean(self.free_energy(self.input)) - T.mean(
            self.free_energy(chain_end))
        # We must not compute the gradient through the gibbs sampling
        gparams = T.grad(cost, self.params, consider_constant=[chain_end])
        # end-snippet-3 start-snippet-4
        # constructs the update dictionary
        for gparam, param in zip(gparams, self.params):
            # make sure that the learning rate is of the right dtype
            updates[param] = param - gparam * T.cast(
                lr,
                dtype=theano.config.floatX
            )
        if persistent:
            # Note that this works only if persistent is a shared variable
            updates[persistent] = nh_samples[-1]
            # pseudo-likelihood is a better proxy for PCD
            monitoring_cost = self.get_pseudo_likelihood_cost(updates)
        else:
            # reconstruction cross-entropy is a better proxy for CD
            monitoring_cost = self.get_reconstruction_cost(updates,
                                                           pre_sigmoid_nvs[-1])
        return monitoring_cost, updates
        # end-snippet-4
    def get_pseudo_likelihood_cost(self, updates):
        """Stochastic approximation to the pseudo-likelihood"""
        # index of bit i in expression p(x_i | x_{\i})
        bit_i_idx = theano.shared(value=0, name='bit_i_idx')
        # binarize the input image by rounding to nearest integer
        xi = T.round(self.input)
        # calculate free energy for the given bit configuration
        fe_xi = self.free_energy(xi)
        # flip bit x_i of matrix xi and preserve all other bits x_{\i}
        # Equivalent to xi[:,bit_i_idx] = 1-xi[:, bit_i_idx], but assigns
        # the result to xi_flip, instead of working in place on xi.
        xi_flip = T.set_subtensor(xi[:, bit_i_idx], 1 - xi[:, bit_i_idx])
        # calculate free energy with bit flipped
        fe_xi_flip = self.free_energy(xi_flip)
        # equivalent to e^(-FE(x_i)) / (e^(-FE(x_i)) + e^(-FE(x_{\i})))
        cost = T.mean(self.n_visible * T.log(T.nnet.sigmoid(fe_xi_flip -
                                                            fe_xi)))
        # increment bit_i_idx % number as part of updates
        updates[bit_i_idx] = (bit_i_idx + 1) % self.n_visible
        return cost
    def get_reconstruction_cost(self, updates, pre_sigmoid_nv):
        """Approximation to the reconstruction error
        Note that this function requires the pre-sigmoid activation as
        input.  To understand why this is so you need to understand a
        bit about how Theano works. Whenever you compile a Theano
        function, the computational graph that you pass as input gets
        optimized for speed and stability.  This is done by changing
        several parts of the subgraphs with others.  One such
        optimization expresses terms of the form log(sigmoid(x)) in
        terms of softplus.  We need this optimization for the
        cross-entropy since sigmoid of numbers larger than 30. (or
        even less then that) turn to 1. and numbers smaller than
        -30. turn to 0 which in terms will force theano to compute
        log(0) and therefore we will get either -inf or NaN as
        cost. If the value is expressed in terms of softplus we do not
        get this undesirable behaviour. This optimization usually
        works fine, but here we have a special case. The sigmoid is
        applied inside the scan op, while the log is
        outside. Therefore Theano will only see log(scan(..)) instead


Please complete the code given below. 
/*
    Copyright 2014 Travel Modelling Group, Department of Civil Engineering, University of Toronto
    This file is part of XTMF.
    XTMF is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    XTMF is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with XTMF.  If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using XTMF;
namespace Tasha.Common
{
    public class TripChain : Attachable, ITripChain
    {
        public static ITashaRuntime TashaRuntime;
        public static int TripChainNumber;
        public static int TripDestinationPlanningDistrct;
        public static int TripDestinationZone;
        public static bool TripHeader;
        public static int TripHouseholdID;
        public static int TripJointTourID;
        public static int TripJointTourRep;
        public static int TripNumber;
        public static int TripObservedMode;
        public static int TripOriginZone;
        public static int TripPersonID;
        public static int TripPlanningDistrictOrigin;
        public static int TripPurposeDestination;
        public static int TripPurposeOrigin;
        public static int TripStartTime;
        private static ConcurrentQueue<TripChain> TripChains = new ConcurrentQueue<TripChain>();
        /// <summary>
        /// The person that this trip chain belongs to
        /// </summary>
        /// <summary>
        ///
        /// </summary>
        /// <param name="person"></param>
        public TripChain(ITashaPerson person)
        {
            Person = person;
            Trips = new List<ITrip>(3 );
        }
        /// <summary>
        /// The End Time of this Trip Chain (The time returned home)
        /// </summary>
        public Time EndTime
        {
            get
            {
                return Trips[Trips.Count - 1].ActivityStartTime;
            }
        }
        public ITripChain GetRepTripChain
        {
            get;
            internal set;
        }
        /// <summary>
        /// Is this a joint trip?
        /// </summary>
        public bool JointTrip
        {
            get
            {
                return JointTripID != 0;
            }
        }
        public List<ITripChain> JointTripChains
        {
            get
            {
                if (!JointTrip) return null;
                List<ITripChain> linkedTripChains = new List<ITripChain>();
                foreach (var p in Person.Household.Persons)
                {
                    foreach (var tripChain in p.TripChains)
                    {
                        if (tripChain.JointTripID == JointTripID)
                            linkedTripChains.Add(tripChain);
                    }
                }
                return linkedTripChains;
            }
        }
        /// <summary>
        /// What is the ID of this joint trip?
        /// </summary>
        public int JointTripID
        {
            get;
            set;
        }
        /// <summary>
        /// Is the owned the Representative for the joint trip?
        /// </summary>
        public bool JointTripRep
        {
            get;
            set;
        }
        public ITashaPerson Person
        {
            get;
            set;
        }
        /// <summary>
        /// The Start Time of this TripChain
        /// </summary>
        public Time StartTime
        {
            get
            {
                return Trips[0].TripStartTime;
            }
        }
        public bool TripChainRequiresPV
        {
            get
            {
                foreach (var t in Trips)
                {
                    if (!t.Mode.NonPersonalVehicle)
                    {
                        return true;
                    }
                }
                return false;
            }
        }
        /// <summary>
        /// The trips in this trip chain
        /// </summary>
        public List<ITrip> Trips
        {
            get;
            set;
        }
        public static IEnumerable<ITrip> GetTrips(ITashaHousehold household)
        {
            foreach (var person in household.Persons)
            {
                foreach (var chain in person.TripChains)
                {
                    foreach (var trip in chain.Trips)
                    {
                        yield return trip;
                    }
                }
            }
        }
        public static TripChain MakeChain(ITashaPerson iPerson)
        {
            if (!TripChains.TryDequeue(out TripChain c))
            {
                return new TripChain(iPerson);
            }
            c.Person = iPerson;
            return c;
        }
        public static void Save(string fileName, IEnumerable<ITashaHousehold> households)
        {
            using (StreamWriter writer = new StreamWriter(fileName))
            {
                //write header
                if (TripHeader)
                    writer.WriteLine("hhld_num,pers_num,trip_num,start_time,mode_prime,purp_orig,pd_orig,gta96_orig,gta01_orig,purp_dest,pd_dest,gta96_dest,gta01_dest,trip_km,jointTourID,jointTourRep" );
                foreach (var household in households)
                {
                    foreach (var trip in GetTrips(household))
                    {
                        int jointTourLeader = 0;
                        int personNum = 1;
                        foreach (var p in household.Persons)
                        {
                            if ((p.TripChains.FindLast((chain) => (chain.JointTripID == trip.TripChain.JointTripID && chain.JointTripRep)) ) != null )
                            {
                                jointTourLeader = personNum;
                                break;
                            }
                            personNum++;
                        }
                        ActivityConverter.Converter.GetTripActivities(trip, trip.TripChain, out char purposeOrigin, out char purposeDestination);
                        string[] attributes = new string[22];
                        for ( int i = 0; i < attributes.Length; i++)
                        {
                            attributes[i] = "";
                        }
                        attributes[TripHouseholdID] = household.HouseholdId.ToString();
                        attributes[TripPersonID] = trip.TripChain.Person.Id.ToString();
                        attributes[TripNumber] = trip.TripNumber.ToString();
                        attributes[TripStartTime] = trip.ActivityStartTime.ToString();
                        attributes[TripObservedMode] = ((char)trip["ObservedMode"]).ToString();
                        attributes[TripPurposeOrigin] = purposeOrigin.ToString();
                        attributes[TripOriginZone] = trip.OriginalZone.ZoneNumber.ToString();
                        attributes[TripPurposeDestination] = purposeDestination.ToString();
                        attributes[TripDestinationZone] = trip.DestinationZone.ZoneNumber.ToString();
                        attributes[TripJointTourID] = trip.TripChain.JointTripID.ToString();
                        attributes[TripJointTourRep] = jointTourLeader.ToString();
                        string line = string.Empty;
                        for ( int i = 0; i < attributes.Length; i++)
                        {
                            line += attributes[i] + ",";
                        }
                        writer.WriteLine(line);
                    }
                }
            }
        }
        public void Recycle()
        {
            Release();
            var trips = Trips;
            for (int i = 0; i < trips.Count; i++)
            {
                trips[i].Recycle();
            }
            Trips.Clear();
            if (Passengers != null )
            {
                Passengers.Clear();
            }
            GetRepTripChain = null;
            JointTripRep = false;
            JointTripID = 0;
            if (JointTripChains != null)
            {
                JointTripChains.Clear();
            }
            GetRepTripChain = null;
            TripChains.Enqueue(this);
        }
        internal static void ReleaseChainPool()
        {
            while (TripChains.TryDequeue(out TripChain c))
            {
            }
        }
        #region ITripChain Members
        public List<ITashaPerson> Passengers
        {
            get { return null; }
        }
        #endregion ITripChain Members
        #region ITripChain Members
        public List<IVehicleType> RequiresVehicle
        {
            get
            {
                List<IVehicleType> v = new List<IVehicleType>();
                foreach (var trip in Trips)
                {
                    if (trip.Mode.RequiresVehicle != null )
                    {
                        if (!v.Contains(trip.Mode.RequiresVehicle))
                        {
                            v.Add(trip.Mode.RequiresVehicle);
                        }
                    }
                }
                return v;
            }
        }
        #endregion ITripChain Members
        #region ITripChain Members
        /// <summary>
        /// Shallow clone of this trip chain (does not clone trips)
        /// </summary>
        /// <returns></returns>
        public ITripChain Clone()
        {


Please complete the code given below. 
// $Id: FigAssociation.java 16903 2009-03-19 20:45:44Z thn $
// Copyright (c) 1996-2009 The Regents of the University of California. All
// Rights Reserved. Permission to use, copy, modify, and distribute this
// software and its documentation without fee, and without a written
// agreement is hereby granted, provided that the above copyright notice
// and this paragraph appear in all copies.  This software program and
// documentation are copyrighted by The Regents of the University of
// California. The software program and documentation are supplied "AS
// IS", without any accompanying services from The Regents. The Regents
// does not warrant that the operation of the program will be
// uninterrupted or error-free. The end-user understands that the program
// was developed for research purposes and is advised not to rely
// exclusively on the program for any reason.  IN NO EVENT SHALL THE
// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
package org.argouml.uml.diagram.ui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import org.apache.log4j.Logger;
import org.argouml.model.AddAssociationEvent;
import org.argouml.model.AttributeChangeEvent;
import org.argouml.model.Model;
import org.argouml.notation.NotationProviderFactory2;
import org.argouml.ui.ArgoJMenu;
import org.argouml.ui.targetmanager.TargetManager;
import org.argouml.uml.diagram.DiagramSettings;
import org.tigris.gef.base.Layer;
import org.tigris.gef.presentation.ArrowHead;
import org.tigris.gef.presentation.ArrowHeadComposite;
import org.tigris.gef.presentation.ArrowHeadDiamond;
import org.tigris.gef.presentation.ArrowHeadGreater;
import org.tigris.gef.presentation.ArrowHeadNone;
import org.tigris.gef.presentation.FigNode;
import org.tigris.gef.presentation.FigText;
/**
 * This class represents the Fig of a binary association on a diagram.
 *
 */
public class FigAssociation extends FigEdgeModelElement {
    private static final Logger LOG = Logger.getLogger(FigAssociation.class);
    /**
     * Group for the FigTexts concerning the source association end.
     */
    private FigAssociationEndAnnotation srcGroup;
    /**
     * Group for the FigTexts concerning the dest association end.
     */
    private FigAssociationEndAnnotation destGroup;
    /**
     * Group for the FigTexts concerning the name and stereotype of the
     * association itself.
     */
    private FigTextGroup middleGroup;
    private FigMultiplicity srcMult;
    private FigMultiplicity destMult;
    /**
     * Don't call this constructor directly. It is public since this
     * is necessary for loading. Use the FigAssociation(Object, Layer)
     * constructor instead!
     * @deprecated for 0.27.3 by tfmorris.  Use 
     * {@link #FigAssociation(Object, DiagramSettings)}.
     */
    @SuppressWarnings("deprecation")
    @Deprecated
    public FigAssociation() {
        super();
        middleGroup = new FigTextGroup();
        
        //////////////////////////////////////////////////////////////////
        // NOTE: If this needs to be updated during the deprecation period
        // also update the constructor below
        //////////////////////////////////////////////////////////////////
        
        // let's use groups to construct the different text sections at
        // the association
        if (getNameFig() != null) {
            middleGroup.addFig(getNameFig());
        }
        
        middleGroup.addFig(getStereotypeFig());
        // Placed perpendicular to midpoint of edge
        addPathItem(middleGroup,
                new PathItemPlacement(this, middleGroup, 50, 25));
        ArgoFigUtil.markPosition(this, 50, 0, 90, 25, Color.yellow);
        
        srcMult = new FigMultiplicity();
        // Placed at a 45 degree angle close to the end
        addPathItem(srcMult, 
                new PathItemPlacement(this, srcMult, 0, 5, 135, 5));
        ArgoFigUtil.markPosition(this, 0, 5, 135, 5, Color.green);
        
        //////////////////////////////////////////////////////////////////
        // NOTE: If this needs to be updated during the deprecation period
        // also update the constructor below
        //////////////////////////////////////////////////////////////////
        
        srcGroup = new FigAssociationEndAnnotation(this);
        addPathItem(srcGroup, 
                new PathItemPlacement(this, srcGroup, 0, 5, -135, 5));
        ArgoFigUtil.markPosition(this, 0, 5, -135, 5, Color.blue);
        destMult = new FigMultiplicity();
        addPathItem(destMult,
                new PathItemPlacement(this, destMult, 100, -5, 45, 5));
        ArgoFigUtil.markPosition(this, 100, -5, 45, 5, Color.red);
        
        //////////////////////////////////////////////////////////////////
        // NOTE: If this needs to be updated during the deprecation period
        // also update the constructor below
        //////////////////////////////////////////////////////////////////
                
        destGroup = new FigAssociationEndAnnotation(this);
        addPathItem(destGroup,
                new PathItemPlacement(this, destGroup, 100, -5, -45, 5));
        ArgoFigUtil.markPosition(this, 100, -5, -45, 5, Color.orange);
                
        setBetweenNearestPoints(true);
    }
    /**
     * Constructor used by PGML parser.
     * 
     * @param owner owning uml element
     * @param settings rendering settings
     */
    public FigAssociation(Object owner, DiagramSettings settings) {
        super(owner, settings);
        
        createNameLabel(owner, settings);
        
        Object[] ends = // UML objects of AssociationEnd type
            Model.getFacade().getConnections(owner).toArray();
        
        srcMult = new FigMultiplicity(ends[0], settings);
        addPathItem(srcMult, 
                new PathItemPlacement(this, srcMult, 0, 5, 135, 5));
        ArgoFigUtil.markPosition(this, 0, 5, 135, 5, Color.green);
        
        srcGroup = new FigAssociationEndAnnotation(this, ends[0], settings);
        addPathItem(srcGroup, 
                new PathItemPlacement(this, srcGroup, 0, 5, -135, 5));
        ArgoFigUtil.markPosition(this, 0, 5, -135, 5, Color.blue);
        destMult = new FigMultiplicity(ends[1], settings);
        addPathItem(destMult,
                new PathItemPlacement(this, destMult, 100, -5, 45, 5));
        ArgoFigUtil.markPosition(this, 100, -5, 45, 5, Color.red);
        
        destGroup = new FigAssociationEndAnnotation(this, ends[1], settings);
        addPathItem(destGroup,
                new PathItemPlacement(this, destGroup, 100, -5, -45, 5));
        ArgoFigUtil.markPosition(this, 100, -5, -45, 5, Color.orange);
        setBetweenNearestPoints(true);
        
        initializeNotationProvidersInternal(owner);
    }
    
    /**
     * Constructor that hooks the Fig to an existing UML element.
     *
     * @param edge the UML element
     * @param lay the layer
     * @deprecated for 0.27.3 by tfmorris.  Use 
     * {@link #FigAssociation(Object, DiagramSettings)}.
     */
    @Deprecated
    public FigAssociation(Object edge, Layer lay) {
        this();
        setOwner(edge);
        setLayer(lay);
    }
    /**
     * Create the main draggable label for the association.
     * This can be overridden in subclasses to change behaviour.
     * TODO: Consider introducing this to FigEdgeModelElement and
     * using throughout all edges.
     * 
     * @param owner owning uml element
     * @param settings rendering settings
     */
    protected void createNameLabel(Object owner, DiagramSettings settings) {
        middleGroup = new FigTextGroup(owner, settings);
     
        // let's use groups to construct the different text sections at
        // the association
        if (getNameFig() != null) {
            middleGroup.addFig(getNameFig());
        }
        middleGroup.addFig(getStereotypeFig());
        addPathItem(middleGroup,
                new PathItemPlacement(this, middleGroup, 50, 25));
        ArgoFigUtil.markPosition(this, 50, 0, 90, 25, Color.yellow);
    }
    
    /**
     * Set the owner.
     * 
     * @param owner ignored
     * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#setOwner(java.lang.Object)
     * @deprecated for 0.27.3 by tfmorris.  Set the owner in the constructor.
     */
    @SuppressWarnings("deprecation")
    @Deprecated
    @Override
    public void setOwner(Object owner) {
        super.setOwner(owner);
        
        Object[] ends = 
            Model.getFacade().getConnections(owner).toArray();
        
        Object source = ends[0];
        Object dest = ends[1];
        
        srcGroup.setOwner(source);
        srcMult.setOwner(source);
        
        destGroup.setOwner(dest);
        destMult.setOwner(dest);
    }
    @Override
    public void renderingChanged() {
        super.renderingChanged();
        /* This fixes issue 4987: */
        srcMult.renderingChanged();
        destMult.renderingChanged();
        srcGroup.renderingChanged();
        destGroup.renderingChanged();
        middleGroup.renderingChanged();
    }
    @Override
    protected void initNotationProviders(Object own) {
        initializeNotationProvidersInternal(own);
    }
    private void initializeNotationProvidersInternal(Object own) {
        super.initNotationProviders(own);
        srcMult.initNotationProviders();
        destMult.initNotationProviders();
    }
    /*
     * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#updateListeners(java.lang.Object, java.lang.Object)
     */
    @Override
    public void updateListeners(Object oldOwner, Object newOwner) {
        Set<Object[]> listeners = new HashSet<Object[]>();
        if (newOwner != null) {
            listeners.add(
                    new Object[] {newOwner,
                                  new String[] {"isAbstract", "remove"}
                    });
        }
        updateElementListeners(listeners);
        /* No further listeners required in this case - the rest is handled 
         * by the notationProvider and sub-Figs. */
    }
    /*
     * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#getNotationProviderType()
     */
    @Override
    protected int getNotationProviderType() {
        return NotationProviderFactory2.TYPE_ASSOCIATION_NAME;
    }
    /*
     * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#textEdited(org.tigris.gef.presentation.FigText)
     */
    @Override
    protected void textEdited(FigText ft) {
        if (getOwner() == null) {
            return;
        }
        super.textEdited(ft);
        
        Collection conn = Model.getFacade().getConnections(getOwner());
        if (conn == null || conn.size() == 0) {
            return;
        }
	if (ft == srcGroup.getRole()) {
	    srcGroup.getRole().textEdited();
	} else if (ft == destGroup.getRole()) {
	    destGroup.getRole().textEdited();
	} else if (ft == srcMult) {
            srcMult.textEdited();
	} else if (ft == destMult) {
            destMult.textEdited();
	}
    }
    /*
     * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#textEditStarted(org.tigris.gef.presentation.FigText)
     */
    @Override
    protected void textEditStarted(FigText ft) {
        if (ft == srcGroup.getRole()) {
            srcGroup.getRole().textEditStarted();
        } else if (ft == destGroup.getRole()) {
            destGroup.getRole().textEditStarted();
        } else if (ft == srcMult) {
            srcMult.textEditStarted();
        } else if (ft == destMult) {
            destMult.textEditStarted();
        } else {
            super.textEditStarted(ft);
        }
    }
    /**
     * Choose the arrowhead style for each end. <p>
     * 
     * TODO: This is called from paint(). Would it not better 
     * be called from renderingChanged()?
     */
    protected void applyArrowHeads() {
        if (srcGroup == null || destGroup == null) {
            /* This only happens if model-change events arrive 
             * before we are completely constructed. */
            return;
        }
        int sourceArrowType = srcGroup.getArrowType();
        int destArrowType = destGroup.getArrowType();
        if (!getSettings().isShowBidirectionalArrows()
                && sourceArrowType > 2
                && destArrowType > 2) {
            sourceArrowType -= 3;
            destArrowType -= 3;
        }
        
        setSourceArrowHead(FigAssociationEndAnnotation
                .ARROW_HEADS[sourceArrowType]);
        setDestArrowHead(FigAssociationEndAnnotation
                .ARROW_HEADS[destArrowType]);
    }
    
    /*
     * @see org.tigris.gef.ui.PopupGenerator#getPopUpActions(java.awt.event.MouseEvent)
     */
    @Override
    public Vector getPopUpActions(MouseEvent me) {
	Vector popUpActions = super.getPopUpActions(me);
        /* Check if multiple items are selected: */
        boolean ms = TargetManager.getInstance().getTargets().size() > 1;
        /* None of the menu-items below apply
         * when multiple modelelements are selected:*/
        if (ms) {
            return popUpActions;
        }
	// x^2 + y^2 = r^2  (equation of a circle)
	Point firstPoint = this.getFirstPoint();
	Point lastPoint = this.getLastPoint();
	int length = getPerimeterLength();
	int rSquared = (int) (.3 * length);
	// max distance is set at 100 pixels, (rSquared = 100^2)
	if (rSquared > 100) {
	    rSquared = 10000;
        } else {
	    rSquared *= rSquared;
        }
	int srcDeterminingFactor =
	    getSquaredDistance(me.getPoint(), firstPoint);
	int destDeterminingFactor =
	    getSquaredDistance(me.getPoint(), lastPoint);
	if (srcDeterminingFactor < rSquared
	    && srcDeterminingFactor < destDeterminingFactor) {
            ArgoJMenu multMenu =
		new ArgoJMenu("menu.popup.multiplicity");
            multMenu.add(ActionMultiplicity.getSrcMultOne());
            multMenu.add(ActionMultiplicity.getSrcMultZeroToOne());
            multMenu.add(ActionMultiplicity.getSrcMultOneToMany());
            multMenu.add(ActionMultiplicity.getSrcMultZeroToMany());
            popUpActions.add(popUpActions.size() - getPopupAddOffset(),
                    multMenu);
            ArgoJMenu aggMenu = new ArgoJMenu("menu.popup.aggregation");
	    aggMenu.add(ActionAggregation.getSrcAggNone());
	    aggMenu.add(ActionAggregation.getSrcAgg());
	    aggMenu.add(ActionAggregation.getSrcAggComposite());
	    popUpActions.add(popUpActions.size() - getPopupAddOffset(),
                    aggMenu);
	} else if (destDeterminingFactor < rSquared) {
            ArgoJMenu multMenu =
		new ArgoJMenu("menu.popup.multiplicity");
	    multMenu.add(ActionMultiplicity.getDestMultOne());
	    multMenu.add(ActionMultiplicity.getDestMultZeroToOne());
	    multMenu.add(ActionMultiplicity.getDestMultOneToMany());
	    multMenu.add(ActionMultiplicity.getDestMultZeroToMany());
	    popUpActions.add(popUpActions.size() - getPopupAddOffset(),
                    multMenu);
            ArgoJMenu aggMenu = new ArgoJMenu("menu.popup.aggregation");
	    aggMenu.add(ActionAggregation.getDestAggNone());
	    aggMenu.add(ActionAggregation.getDestAgg());
	    aggMenu.add(ActionAggregation.getDestAggComposite());
	    popUpActions
                    .add(popUpActions.size() - getPopupAddOffset(), aggMenu);
	}
	// else: No particular options for right click in middle of line
	// Options available when right click anywhere on line
	Object association = getOwner();
	if (association != null) {
	    // Navigability menu with suboptions built dynamically to
	    // allow navigability from atart to end, from end to start
	    // or bidirectional
	    Collection ascEnds = Model.getFacade().getConnections(association);
            Iterator iter = ascEnds.iterator();
	    Object ascStart = iter.next();
	    Object ascEnd = iter.next();
	    if (Model.getFacade().isAClassifier(
	            Model.getFacade().getType(ascStart))
                    && Model.getFacade().isAClassifier(
                            Model.getFacade().getType(ascEnd))) {
                ArgoJMenu navMenu =
		    new ArgoJMenu("menu.popup.navigability");
		navMenu.add(ActionNavigability.newActionNavigability(
                    ascStart,
		    ascEnd,
		    ActionNavigability.BIDIRECTIONAL));
		navMenu.add(ActionNavigability.newActionNavigability(
                    ascStart,
		    ascEnd,
		    ActionNavigability.STARTTOEND));
		navMenu.add(ActionNavigability.newActionNavigability(
                    ascStart,
                    ascEnd,
                    ActionNavigability.ENDTOSTART));
		popUpActions.add(popUpActions.size() - getPopupAddOffset(),
                        navMenu);
	    }
	}
	return popUpActions;
    }
    /**
     * Updates the multiplicity fields.
     */
    protected void updateMultiplicity() {
        if (getOwner() != null 
                && srcMult.getOwner() != null 
                && destMult.getOwner() != null) {
            srcMult.setText();
            destMult.setText();
        }
    }
    /*
     * @see org.tigris.gef.presentation.Fig#paint(java.awt.Graphics)
     */
    @Override
    public void paint(Graphics g) {
        if (getOwner() == null ) {
            LOG.error("Trying to paint a FigAssociation without an owner. ");
        } else {
            applyArrowHeads(); 
        }
        if (getSourceArrowHead() != null && getDestArrowHead() != null) {
            getSourceArrowHead().setLineColor(getLineColor());
            getDestArrowHead().setLineColor(getLineColor());
        }
        super.paint(g);
    }
    /*
     * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#paintClarifiers(java.awt.Graphics)
     */
    @Override
    public void paintClarifiers(Graphics g) {
        indicateBounds(getNameFig(), g);
        indicateBounds(srcMult, g);
        indicateBounds(srcGroup.getRole(), g);
        indicateBounds(destMult, g);
        indicateBounds(destGroup.getRole(), g);
        super.paintClarifiers(g);
    }
    /**
     * @return Returns the middleGroup.
     */
    protected FigTextGroup getMiddleGroup() {
        return middleGroup;
    }
    
    /**
     * Lays out the association edges as any other edge except for
     * special rules for an association that loops back to the same
     * class. For this it is snapped back to the bottom right corner
     * if it resized to the point of not being visible.
     * @see org.tigris.gef.presentation.FigEdgePoly#layoutEdge()
     */
    @Override
    protected void layoutEdge() {
        FigNode sourceFigNode = getSourceFigNode();
        Point[] points = getPoints();
        if (points.length < 3
                && sourceFigNode != null
                && getDestFigNode() == sourceFigNode) {
            Rectangle rect = new Rectangle(
                    sourceFigNode.getX() + sourceFigNode.getWidth() - 20,
                    sourceFigNode.getY() + sourceFigNode.getHeight() - 20,
                    40,
                    40);
            points = new Point[5];
            points[0] = new Point(rect.x, rect.y + rect.height / 2);
            points[1] = new Point(rect.x, rect.y + rect.height);
            points[2] = new Point(rect.x + rect.width , rect.y + rect.height);
            points[3] = new Point(rect.x + rect.width , rect.y);
            points[4] = new Point(rect.x + rect.width / 2, rect.y);
            setPoints(points);
        } else {
            super.layoutEdge();
        }
    }
    
    /**
     * If the name is updated, update the bounds of the middle group.
     * This makes the selection box appear correctly during prop-panel edit.
     * This is a temporary solution, until a better architecture is decided 
     * upon, see issue 5477 and 
     * http://argouml.tigris.org/issues/show_bug.cgi?id=5621#desc19.
     * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#updateNameText()
     */
    protected void updateNameText() {
        super.updateNameText();
        // TODO: Without the null check the following throws a NPE so many
        // times when it is called from FigEdgeModelElement.modelChanged(),
        // we need to think about it.
        if (middleGroup != null) {
            middleGroup.calcBounds();
        }
    }
    
    
} /* end class FigAssociation */
/**
 * A Fig representing the multiplicity of some model element.
 * This has potential reuse for other edges showing multiplicity. <p>
 * 
 * The owner is an AssociationEnd.
 * 
 * @author Bob Tarling
 */
class FigMultiplicity extends FigSingleLineTextWithNotation {
    @SuppressWarnings("deprecation")
    @Deprecated
    FigMultiplicity() {
        super(X0, Y0, 90, 20, false, new String[] {"multiplicity"});
        setTextFilled(false);
        setJustification(FigText.JUSTIFY_CENTER);
    }
    FigMultiplicity(Object owner, DiagramSettings settings) {
        super(owner, new Rectangle(X0, Y0, 90, 20), settings, false,
                "multiplicity");
        setTextFilled(false);
        setJustification(FigText.JUSTIFY_CENTER);
    }
    @Override
    protected int getNotationProviderType() {
        return NotationProviderFactory2.TYPE_MULTIPLICITY;
    }
}
/**
 * A textual Fig representing the ordering of some model element,
 * i.e. "{ordered}" or nothing.
 * This has potential reuse for other edges showing ordering. <p>
 * 
 * This Fig is not editable by the user.
 * 
 * @author Bob Tarling
 */
class FigOrdering extends FigSingleLineText {
    private static final long serialVersionUID = 5385230942216677015L;
    @SuppressWarnings("deprecation")
    @Deprecated
    FigOrdering() {
        super(X0, Y0, 90, 20, false, "ordering");
        setTextFilled(false);
        setJustification(FigText.JUSTIFY_CENTER);
        setEditable(false);
    }
    
    FigOrdering(Object owner, DiagramSettings settings) {
        super(owner, new Rectangle(X0, Y0, 90, 20), settings, false, 
                "ordering");
        setTextFilled(false);
        setJustification(FigText.JUSTIFY_CENTER);
        setEditable(false);
    }
    
    @Override
    protected void setText() {
        assert getOwner() != null;
        if (getSettings().getNotationSettings().isShowProperties()) {
            setText(getOrderingName(Model.getFacade().getOrdering(getOwner())));
        } else {
            setText("");
        }
        damage();
    }
    /**
     * Returns the name of the OrderingKind.
     *
     * @param orderingKind the kind of ordering
     * @return "{ordered}" or "", the latter if null or unordered
     */
    private String getOrderingName(Object orderingKind) {
        if (orderingKind == null) {
            return "";
        }
        if (Model.getFacade().getName(orderingKind) == null) {
            return "";
        }
        if ("".equals(Model.getFacade().getName(orderingKind))) {
            return "";
        }
        if ("unordered".equals(Model.getFacade().getName(orderingKind))) {
            return "";
        }
        // TODO: I18N
        return "{" + Model.getFacade().getName(orderingKind) + "}";
    }
}
/**
 * A Fig representing the association end role of some model element.
 * 
 * @author Bob Tarling
 */
class FigRole extends FigSingleLineTextWithNotation {
    /**
     * @deprecated for 0.27.3 by tfmorris.  Use 
     * {@link FigRole#FigRole(Object, DiagramSettings)}/
     */
    @SuppressWarnings("deprecation")
    @Deprecated
    FigRole() {
        super(X0, Y0, 90, 20, false, (String[]) null 
        // no need to listen to these property changes - the 
        // notationProvider takes care of registering these.
                /*, new String[] {"name", "visibility", "stereotype"}*/
                );
        setTextFilled(false);
        setJustification(FigText.JUSTIFY_CENTER);
    }
    
    FigRole(Object owner, DiagramSettings settings) {
        super(owner, new Rectangle(X0, Y0, 90, 20), settings, false, 
                (String[]) null 
        // no need to listen to these property changes - the 
        // notationProvider takes care of this.
                /*, new String[] {"name", "visibility", "stereotype"}*/
                );
        setTextFilled(false);
        setJustification(FigText.JUSTIFY_CENTER);
        setText();
    }
    protected int getNotationProviderType() {
        return NotationProviderFactory2.TYPE_ASSOCIATION_END_NAME;
    }
    
    /**
     * Property change listener to recalculate bounds of enclosing
     * group whenever any properties of the FigRole get changed.
     * This is only really needed for the name, see issue 5621.
     * @param pce The property change event to process.
     * @see org.argouml.uml.diagram.ui.FigSingleLineTextWithNotation#propertyChange(java.beans.PropertyChangeEvent)
     */
    @Override
    public void propertyChange(PropertyChangeEvent pce) {
        super.propertyChange(pce);
        this.getGroup().calcBounds();
    }
}
/**
 * The arrowhead and the group of labels shown at the association end: 
 * the role name and the ordering property. 
 * This does not include the multiplicity. <p>
 * 
 * This class does not yet support arrows for a FigAssociationEnd, 
 * as is used for N-ary associations.
 */
class FigAssociationEndAnnotation extends FigTextGroup {
    private static final long serialVersionUID = 1871796732318164649L;
    
    private static final ArrowHead NAV_AGGR =
        new ArrowHeadComposite(ArrowHeadDiamond.WhiteDiamond,
                   new ArrowHeadGreater());
    private static final ArrowHead NAV_COMP =
        new ArrowHeadComposite(ArrowHeadDiamond.BlackDiamond,
                   new ArrowHeadGreater());
    // These are a list of arrow types. Positioning is important as we subtract
    // 3 to convert a navigable arrow to a non navigable with the same
    // aggregation
    private static final int NONE = 0;
    private static final int AGGREGATE = 1;
    private static final int COMPOSITE = 2;
    private static final int NAV_NONE = 3;
    private static final int NAV_AGGREGATE = 4;
    private static final int NAV_COMPOSITE = 5;
    
    /**
     * All the arrow head types.
     */
    public static final ArrowHead[] ARROW_HEADS = new ArrowHead[6];
    static {
        ARROW_HEADS[NONE] = ArrowHeadNone.TheInstance;
        ARROW_HEADS[AGGREGATE] = ArrowHeadDiamond.WhiteDiamond;
        ARROW_HEADS[COMPOSITE] = ArrowHeadDiamond.BlackDiamond;
        ARROW_HEADS[NAV_NONE] = new ArrowHeadGreater();
        ARROW_HEADS[NAV_AGGREGATE] = NAV_AGGR;
        ARROW_HEADS[NAV_COMPOSITE] = NAV_COMP;
    }
    
    private FigRole role;
    private FigOrdering ordering;
    private int arrowType = 0;
    private FigEdgeModelElement figEdge;
    @SuppressWarnings("deprecation")
    @Deprecated
    FigAssociationEndAnnotation(FigEdgeModelElement edge) {
        figEdge = edge;
        


Please complete the code given below. 
// 
// Copyright (c) 2004-2006 Jaroslaw Kowalski <jaak@jkowalski.net>
// 
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
// * Redistributions of source code must retain the above copyright notice, 
//   this list of conditions and the following disclaimer. 
// 
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution. 
// 
// * Neither the name of Jaroslaw Kowalski nor the names of its 
//   contributors may be used to endorse or promote products derived from this
//   software without specific prior written permission. 
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
// THE POSSIBILITY OF SUCH DAMAGE.
// 
#if !NETCF
using System;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using NLog.Internal;
using NLog.Config;
using System.Collections.Generic;
namespace NLog.Win32.Targets
{
    /// <summary>
    /// Increments specified performance counter on each write.
    /// </summary>
    /// <example>
    /// <p>
    /// To set up the target in the <a href="config.html">configuration file</a>, 
    /// use the following syntax:
    /// </p>
    /// <code lang="XML" src="examples/targets/Configuration File/PerfCounter/NLog.config" />
    /// <p>
    /// This assumes just one target and a single rule. More configuration
    /// options are described <a href="config.html">here</a>.
    /// </p>
    /// <p>
    /// To set up the log target programmatically use code like this:
    /// </p>
    /// <code lang="C#" src="examples/targets/Configuration API/PerfCounter/Simple/Example.cs" />
    /// </example>
    /// <remarks>
    /// TODO:
    /// 1. Unable to create a category allowing multiple counter instances (.Net 2.0 API only, probably)
    /// 2. Is there any way of adding new counters without deleting the whole category?
    /// 3. There should be some mechanism of resetting the counter (e.g every day starts from 0), or auto-switching to 
    ///    another counter instance (with dynamic creation of new instance). This could be done with layouts. 
    /// </remarks>
    [Target("PerfCounter")]
    [SupportedRuntime(OS=RuntimeOS.WindowsNT,Framework=RuntimeFramework.DotNetFramework)]
    public class PerfCounterTarget : Target
    {
        private bool _autoCreate = false;
        private string _categoryName;
        private string _counterName;
        private string _instanceName = "";
        private PerformanceCounterType _counterType = PerformanceCounterType.NumberOfItems32;
		private static List<PerfCounterTarget> _perfCounterTargets = new List<PerfCounterTarget>();
        private PerformanceCounter _perfCounter = null;
        private bool _operational = true;
            
        /// <summary>
        /// Creates a new instance of <see cref="PerfCounterTarget"/>.
        /// </summary>
        public PerfCounterTarget()
        {
            lock(_perfCounterTargets)
            {
                if (!_perfCounterTargets.Contains(this)) _perfCounterTargets.Add(this);
            }
        }
        /// <summary>
        /// Increments the configured performance counter.
        /// </summary>
        /// <param name="logEvent">log event</param>
        public override void Write(LogEventInfo logEvent)
        {
            if (!_operational) return;
            if (_perfCounter == null) InitializePerfCounter();
            if (_perfCounter == null) return; //not operational
            
            bool ok = false;
            try 
            {
                _perfCounter.Increment();
                ok = true;
            }
            finally
            {
                _operational = ok;
            }
        }
        
        /// <summary>
        /// Whether performance counter should be automatically created.
        /// </summary>
        public bool AutoCreate
        {
            get {return _autoCreate; }
            set {_autoCreate = value; }
        }
        
        /// <summary>
        /// Performance counter category.
        /// </summary>
        [RequiredParameter]
        public string CategoryName
        {
            get {return _categoryName; }
            set {_categoryName = value; }
        }
        
        /// <summary>
        /// Name of the performance counter.
        /// </summary>
        [RequiredParameter]
        public string CounterName
        {
            get {return _counterName; }
            set {_counterName = value; }
        }
        
        /// <summary>
        /// Instance name.
        /// </summary>
        public string InstanceName
        {
            get {return _instanceName; }
            set {_instanceName = value; }
        }
        
        /// <summary>
        /// Performance counter type.
        /// </summary>
        public PerformanceCounterType CounterType
        {
            get { return _counterType; }
            set { _counterType = value; }
        }
        
        private void InitializePerfCounter()
        {
            lock(this)
            {
                _operational = true;
                try
                {
                    if (_perfCounter != null) { _perfCounter.Close(); _perfCounter = null; }
                    if (_categoryName == null || _counterName == null) 
                    {
                        throw new Exception("Missing category name or counter name for target: " + Name);
                    }
                    
                    if (!PerformanceCounterCategory.Exists(CategoryName) || !PerformanceCounterCategory.CounterExists(CounterName, CategoryName))
                    {
						List<PerfCounterTarget> targets = new List<PerfCounterTarget>();
                        bool doCreate = false;
                        foreach(PerfCounterTarget t in _perfCounterTargets)
                        {
                            if (t.CategoryName == CategoryName)
                            {
                                targets.Add(t);
                                if (t.AutoCreate) doCreate = true;
                            }
                        }
                        
                        if (doCreate)
                        {
                            if (PerformanceCounterCategory.Exists(CategoryName))
                            {
                                //delete the whole category and rebuild from scratch
                                PerformanceCounterCategory.Delete(CategoryName);
                            }
                            
                            CounterCreationDataCollection ccds = new CounterCreationDataCollection();
                            foreach(PerfCounterTarget t in targets)
                            {
                                CounterCreationData ccd = new CounterCreationData();
                                ccd.CounterName = t._counterName;
                                ccd.CounterType = t._counterType;  
                                ccds.Add(ccd);                                    
                            }
#if DOTNET_2_0
                            PerformanceCounterCategory.Create(CategoryName,
                                "Category created by NLog",
                                (InstanceName != null) ? PerformanceCounterCategoryType.MultiInstance : PerformanceCounterCategoryType.SingleInstance,
                                ccds);
#else
                            PerformanceCounterCategory.Create(CategoryName,"Category created by NLog",ccds);
#endif
                        }
                        else
                        {
                            throw new Exception(string.Format("Counter does not exist: {0}|{1}", CounterName, CategoryName));
                        }
                    }
                    
                    _perfCounter = new PerformanceCounter(CategoryName, CounterName, InstanceName, false);
                    _operational = true;
                }
                catch(Exception ex)
                {
                    _operational = false;
                    _perfCounter = null;


Please complete the code given below. 
import subprocess
import cfg
import util
import shutil
import os
import time
import tempfile
import easywebdav
import filecmp
import threading
import Queue
import sys
import random
import hashlib
from nose.tools import with_setup
from nose.tools import assert_raises
#
# NOTE: following tests have been implemented using easywebdav instead of davfs2
#
pjoin = os.path.join
assert subprocess # pyflakes
assert cfg # pyflakes
@with_setup(util.setup_func, util.teardown_func)
def test_case_01_get():
    full_name = pjoin(cfg.webdav_backend_directory, "foo")
    subprocess.call(["dd","if=/dev/urandom",'of=%s' % full_name,"bs=100kB","count=10"],
                    stderr=util.FNULL)
    # could be as well a list
    # Im using a queue here to make sure it's thread safe
    test_fails = Queue.Queue()
    def download_foo(c):
        try:
            with tempfile.NamedTemporaryFile() as f:
                c.download("foo",f) 
                f.flush()
                assert filecmp.cmp(full_name, f.name)
        except Exception:
            test_fails.put( sys.exc_info() )
    connections = [util.connect_easywebdav() for _ in range(100)]
    ts = [threading.Thread(target=download_foo,args=(c,) )
            for c in connections ]
    for t in ts:
        t.start()
    for t in ts:
        t.join()
    try:
        while True:
            exc = test_fails.get(block=False)
            raise exc[0], exc[1], exc[2]
    except Queue.Empty:
        pass
@with_setup(util.setup_func, util.teardown_func)
def test_case_02_mkcol():
    # could be as well a list
    # Im using a queue here to make sure it's thread safe
    test_fails = Queue.Queue()
    def mkcol_foo(c):
        try:
            try:
                c.mkdir("foo")
            except easywebdav.OperationFailed:
                pass
        except Exception:
            test_fails.put( sys.exc_info() )
    connections = [util.connect_easywebdav() for _ in range(100)]
    ts = [threading.Thread(target=mkcol_foo,args=(c,) )
            for c in connections ]
    for t in ts:
        t.start()
    for t in ts:
        t.join()
    try:
        while True:
            exc = test_fails.get(block=False)
            raise exc[0], exc[1], exc[2]
    except Queue.Empty:
        pass
    assert os.path.isdir( pjoin( cfg.webdav_backend_directory, "foo") )
@with_setup(util.setup_func, util.teardown_func)
def test_case_03_mkcol_different():
    # could be as well a list
    # Im using a queue here to make sure it's thread safe
    test_fails = Queue.Queue()
    def mkcol(c,name):
        try:
            c.mkdir(name)
        except Exception:
            test_fails.put( sys.exc_info() )
    connections = [util.connect_easywebdav() for _ in range(100)]
    ts = [threading.Thread(target=mkcol, args=(c,"foo%d" % i) )
            for i,c in enumerate(connections) ]
    for t in ts:
        t.start()
    for t in ts:
        t.join()
    try:
        while True:
            exc = test_fails.get(block=False)
            raise exc[0], exc[1], exc[2]
    except Queue.Empty:
        pass
    for i in range(100):
        assert os.path.isdir( pjoin( cfg.webdav_backend_directory, "foo%d" %i) )
@with_setup(util.setup_func, util.teardown_func)
def test_case_04_put():
    # could be as well a list
    # Im using a queue here to make sure it's thread safe
    test_fails = Queue.Queue()
    checksums = Queue.Queue()
    def put(c):
        try:
            with tempfile.TemporaryFile() as f:
                rand_1mb = ''.join( [ chr( random.randint(0,100) ) for _ in range(1024*1024) ] )
                f.write(rand_1mb)
                f.seek(0)
                c.upload(f, "foo")
                m = hashlib.md5()
                m.update( rand_1mb )
                checksums.put( m.digest() )
        except Exception:
            test_fails.put( sys.exc_info() )
    connections = [util.connect_easywebdav() for _ in range(10)]
    ts = [threading.Thread(target=put, args=(c,) )
            for c in connections ]
    for t in ts:
        t.start()
    for t in ts:
        t.join()
    try:
        while True:
            exc = test_fails.get(block=False)
            raise exc[0], exc[1], exc[2]
    except Queue.Empty:
        pass
    full_name = pjoin( cfg.webdav_backend_directory, "foo" )
    assert os.path.isfile( full_name )
    with open(full_name, "rb") as f:
        m = hashlib.md5()
        m.update( f.read() )
        expected_checksum = m.digest()
    while True:
        try:
            checksum = checksums.get(block=False)
            if checksum == expected_checksum:
                break
        except Queue.Empty:
            assert False # file uploaded doesn't match any of the orig files!
@with_setup(util.setup_func, util.teardown_func)
def test_case_05_put_diff():
    # could be as well a list
    # Im using a queue here to make sure it's thread safe
    test_fails = Queue.Queue()
    checksums = Queue.Queue()
    def put(c,name):
        try:
            with tempfile.TemporaryFile() as f:
                rand_1mb = ''.join( [ chr( random.randint(0,100) ) for _ in range(1024*1024) ] )
                f.write(rand_1mb)
                f.seek(0)
                c.upload(f, name)
                m = hashlib.md5()
                m.update( rand_1mb )
                checksums.put( (name,m.digest()) )
        except Exception:
            test_fails.put( sys.exc_info() )
    connections = [util.connect_easywebdav() for _ in range(10)]
    ts = [threading.Thread(target=put, args=(c,"foo-%d" % i) )
            for i,c in enumerate(connections) ]
    for t in ts:
        t.start()
    for t in ts:
        t.join()
    try:
        while True:
            exc = test_fails.get(block=False)
            raise exc[0], exc[1], exc[2]
    except Queue.Empty:
        pass
    
    assert checksums.qsize() == 10
    try:
        while True:


Please complete the code given below. 
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, see
# <http://www.gnu.org/licenses/>.
"""
sibilant.pseudops.stack
Stack counting utilities for sibiliant pseudops blocks
author: Christopher O'Brien <obriencj@gmail.com>
license: LGPL v.3
"""
from . import Pseudop, Opcode
from ..lib import SibilantException
__all__ = (
    "StackCounter", "StackUnderrun", "StackMismatch",
    "stacker", "stacking",
    "stacking_pop_args_push", "stacking_push_args_pop",
)
class StackUnderrun(SibilantException):
    def __init__(self, stack_size, pop_size):
        self.start_size = stack_size
        self.pop_size = pop_size
        msg = "stack size underrun, %i decremented by %i"
        super().__init__(msg % (stack_size, pop_size))
class StackMismatch(SibilantException):
    def __init__(self, label, label_size, jump_size):
        self.label = label
        self.label_size = label_size
        self.jump_size = jump_size
        msg = "mismatch between label %r stack: %i and origin stack: %i"
        super().__init__(msg % (label, label_size, jump_size))
class MetaStackCounter(type):
    def __init__(self, name, bases, members):
        # the _translations_ member is merged together with those of
        # the bases, to provide a sort of inheritance.
        stk = {}
        for base in bases:
            stk.update(getattr(base, "_stackers_", {}))
        stk.update(members.get("_stackers_", {}))
        # we also hunt for decorated callable members to inject into
        # the _stackers_
        for memb in members.values():
            if callable(memb):
                trop = getattr(memb, "_stacks_", None)
                if trop is not None:
                    stk[trop] = memb
        members["_stackers_"] = stk
        self._stackers_ = stk
        return super().__init__(name, bases, members)
def stacker(pseudop):
    def decorator(member):
        member._stacks_ = pseudop
        return member
    return decorator
def stacking(pushc, popc):
    def pop_then_push(self, pseudop, args, push, pop):
        if popc:
            pop(popc)
        if pushc:
            push(pushc)
    return pop_then_push
def stacking_pop_args_push(pushc):
    def pop_args_then_push(self, pseudop, args, push, pop):
        pop(args[0])
        if pushc:
            push(pushc)
    return pop_args_then_push
def stacking_push_args_pop(popc):
    def pop_then_push_args(self, pseudops, args, push, pop):
        if popc:
            pop(popc)
        push(args[0])
    return pop_then_push_args
class StackCounter(metaclass=MetaStackCounter):
    _stackers_ = {
        Pseudop.POSITION: stacking(0, 0),
        Pseudop.DEL_VAR: stacking(0, 0),
        Pseudop.DEL_GLOBAL: stacking(0, 0),
        Pseudop.ROT_TWO: stacking(0, 0),
        Pseudop.ROT_THREE: stacking(0, 0),
        Pseudop.CONST: stacking(1, 0),
        Pseudop.DUP: stacking(1, 0),
        Pseudop.GET_VAR: stacking(1, 0),
        Pseudop.GET_GLOBAL: stacking(1, 0),
        Pseudop.BREAK_LOOP: stacking(1, 0),
        Pseudop.FOR_ITER: stacking(1, 0),
        Pseudop.IMPORT_FROM: stacking(1, 0),
        Pseudop.CONTINUE_LOOP: stacking(1, 0),
        Pseudop.LOAD_CELL: stacking(1, 0),
        Pseudop.GET_ATTR: stacking(1, 1),
        Pseudop.UNARY_POSITIVE: stacking(1, 1),
        Pseudop.UNARY_NEGATIVE: stacking(1, 1),
        Pseudop.UNARY_NOT: stacking(1, 1),
        Pseudop.UNARY_INVERT: stacking(1, 1),
        Pseudop.ITER: stacking(1, 1),
        Pseudop.GET_YIELD_FROM_ITER: stacking(1, 1),
        Pseudop.GET_AWAITABLE: stacking(1, 1),
        Pseudop.YIELD_VAL: stacking(1, 1),
        Pseudop.COMPARE_OP: stacking(1, 2),
        Pseudop.GET_ITEM: stacking(1, 2),
        Pseudop.BINARY_ADD: stacking(1, 2),
        Pseudop.BINARY_SUBTRACT: stacking(1, 2),
        Pseudop.BINARY_MULTIPLY: stacking(1, 2),
        Pseudop.BINARY_MATRIX_MULTIPLY: stacking(1, 2),
        Pseudop.BINARY_TRUE_DIVIDE: stacking(1, 2),
        Pseudop.BINARY_FLOOR_DIVIDE: stacking(1, 2),
        Pseudop.BINARY_POWER: stacking(1, 2),
        Pseudop.BINARY_MODULO: stacking(1, 2),
        Pseudop.BINARY_LSHIFT: stacking(1, 2),
        Pseudop.BINARY_RSHIFT: stacking(1, 2),
        Pseudop.BINARY_AND: stacking(1, 2),
        Pseudop.BINARY_XOR: stacking(1, 2),
        Pseudop.BINARY_OR: stacking(1, 2),
        Pseudop.IMPORT_NAME: stacking(1, 2),
        Pseudop.SET_ATTR: stacking(0, 2),
        Pseudop.DEL_ITEM: stacking(0, 2),
        Pseudop.SET_ITEM: stacking(0, 3),
        Pseudop.POP: stacking(0, 1),
        Pseudop.DEL_ATTR: stacking(0, 1),
        Pseudop.SET_GLOBAL: stacking(0, 1),
        Pseudop.SET_LOCAL: stacking(0, 1),
        Pseudop.SET_VAR: stacking(0, 1),
        Pseudop.RET_VAL: stacking(0, 1),
        Pseudop.YIELD_FROM: stacking(1, 2),
        Pseudop.SETUP_EXCEPT: stacking(6, 0),
        Pseudop.POP_EXCEPT: stacking(0, 3),
        Pseudop.SETUP_WITH: stacking(6, 0),
        Pseudop.WITH_CLEANUP_START: stacking(7, 0),
        Pseudop.WITH_CLEANUP_FINISH: stacking(0, 7),
        Pseudop.SETUP_FINALLY: stacking(6, 0),
        Pseudop.END_FINALLY: stacking(0, 6),
        Pseudop.BUILD_LIST: stacking_pop_args_push(1),
        Pseudop.BUILD_SET: stacking_pop_args_push(1),
        Pseudop.BUILD_TUPLE: stacking_pop_args_push(1),
        Pseudop.BUILD_TUPLE_UNPACK: stacking_pop_args_push(1),
        Pseudop.BUILD_MAP_UNPACK: stacking_pop_args_push(1),
        Pseudop.BUILD_SLICE: stacking_pop_args_push(1),
        Pseudop.RAISE: stacking_pop_args_push(1),
        Pseudop.FAUX_POP: stacking_pop_args_push(0),
        Pseudop.UNPACK_SEQUENCE: stacking_push_args_pop(1),
        Pseudop.FAUX_PUSH: stacking_push_args_pop(0),
    }
    # @stacker(Pseudop.LAMBDA)
    # def stacks_lambda(self, pseudop, args, push, pop):
    #    pop(args[1])
    #    a = len(args[0].co_freevars)
    #    if a:
    #        push(a)
    #        pop(a)
    #    push(2)
    #    pop(2)
    #    push()
    @stacker(Pseudop.BUILD_MAP)
    def stacker_build_map(self, pseudop, args, push, pop):
        pop(args[0] * 2)
        push()
    @stacker(Pseudop.UNPACK_EX)
    def stacker_unpack_ex(self, pseudop, args, push, pop):
        pop()
        push(args[0] + args[1] + 1)
    @stacker(Pseudop.SETUP_LOOP)
    def stacker_setup_loop(self, pseudop, args, push, pop):
        push(Opcode.SETUP_LOOP.stack_effect(1))
    @stacker(Pseudop.POP_BLOCK)
    def stacker_pop_block(self, pseudop, args, push, pop):
        push(Opcode.POP_BLOCK.stack_effect())
    @stacker(Pseudop.LABEL)
    def stacker_label(self, pseudop, args, push, pop):
        stac = self.stack_count
        stac = self.labels.setdefault(args[0], stac)
        self.stack_count = stac
    @stacker(Pseudop.BLOCK)
    def stacker_block(self, pseudop, args, push, pop):
        block = args[0]
        block_i, block_max = block.max_stack(self.compiler)
        push(block_max)
        pop(block_max)
    @stacker(Pseudop.JUMP)
    def stacker_jump(self, pseudop, args, push, pop):
        stac = self.stack_count


Please complete the code given below. 
# Copyright (c) 2011-2015 Rusty Wagner
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
from BinaryData import *
from Structure import *
from HexEditor import *
from View import *
class ElfFile(BinaryAccessor):
	def __init__(self, data):
		self.data = data
		self.valid = False
		self.callbacks = []
		self.symbols_by_name = {}
		self.symbols_by_addr = {}
		if not self.is_elf():
			return
		try:
			self.tree = Structure(self.data)
			self.header = self.tree.struct("ELF header", "header")
			self.header.struct("ELF identification", "ident")
			self.header.ident.uint32("magic")
			self.header.ident.uint8("file_class")
			self.header.ident.uint8("encoding")
			self.header.ident.uint8("version")
			self.header.ident.uint8("abi")
			self.header.ident.uint8("abi_version")
			self.header.ident.bytes(7, "pad")
			self.header.uint16("type")
			self.header.uint16("arch")
			self.header.uint32("version")
			self.symbol_table_section = None
			self.dynamic_symbol_table_section = None
			if self.header.ident.file_class == 1: # 32-bit
				self.header.uint32("entry")
				self.header.uint32("program_header_offset")
				self.header.uint32("section_header_offset")
				self.header.uint32("flags")
				self.header.uint16("header_size")
				self.header.uint16("program_header_size")
				self.header.uint16("program_header_count")
				self.header.uint16("section_header_size")
				self.header.uint16("section_header_count")
				self.header.uint16("string_table")
				try:
					self.sections = self.tree.array(self.header.section_header_count, "sections")
					for i in range(0, self.header.section_header_count):
						section = self.sections[i]
						section.seek(self.header.section_header_offset + (i * 40))
						section.uint32("name")
						section.uint32("type")
						section.uint32("flags")
						section.uint32("addr")
						section.uint32("offset")
						section.uint32("size")
						section.uint32("link")
						section.uint32("info")
						section.uint32("align")
						section.uint32("entry_size")
						if section.type == 2:
							self.symbol_table_section = section
						elif section.type == 11:
							self.dynamic_symbol_table_section = section
				except:
					# Section headers are not required to load an ELF, skip errors
					self.sections = self.tree.array(0, "sections")
					pass
				self.program_headers = self.tree.array(self.header.program_header_count, "programHeaders")
				for i in range(0, self.header.program_header_count):
					header = self.program_headers[i]
					header.seek(self.header.program_header_offset + (i * 32))
					header.uint32("type")
					header.uint32("offset")
					header.uint32("virtual_addr")
					header.uint32("physical_addr")
					header.uint32("file_size")
					header.uint32("memory_size")
					header.uint32("flags")
					header.uint32("align")
				# Parse symbol tables
				self.symbols_by_name["_start"] = self.entry()
				self.symbols_by_addr[self.entry()] = "_start"
				try:
					if self.symbol_table_section:
						self.symbol_table = self.tree.array(self.symbol_table_section.size / 16, "Symbols", "symbols")
						self.parse_symbol_table_32(self.symbol_table, self.symbol_table_section, self.sections[self.symbol_table_section.link])
					if self.dynamic_symbol_table_section:
						self.dynamic_symbol_table = self.tree.array(self.dynamic_symbol_table_section.size / 16, "Symbols", "symbols")
						self.parse_symbol_table_32(self.dynamic_symbol_table, self.dynamic_symbol_table_section, self.sections[self.dynamic_symbol_table_section.link])
				except:
					# Skip errors in symbol table
					pass
				# Parse relocation tables
				self.plt = {}
				for section in self.sections:
					if section.type == 9:
						self.parse_reloc_32(section)
					elif section.type == 4:
						self.parse_reloca_32(section)
			elif self.header.ident.file_class == 2: # 64-bit
				self.header.uint64("entry")
				self.header.uint64("program_header_offset")
				self.header.uint64("section_header_offset")
				self.header.uint32("flags")
				self.header.uint16("header_size")
				self.header.uint16("program_header_size")
				self.header.uint16("program_header_count")
				self.header.uint16("section_header_size")
				self.header.uint16("section_header_count")
				self.header.uint16("string_table")
				try:
					self.sections = self.tree.array(self.header.section_header_count, "sections")
					for i in range(0, self.header.section_header_count):
						section = self.sections[i]
						section.seek(self.header.section_header_offset + (i * 64))
						section.uint32("name")
						section.uint32("type")
						section.uint64("flags")
						section.uint64("addr")
						section.uint64("offset")
						section.uint64("size")
						section.uint32("link")
						section.uint32("info")
						section.uint64("align")
						section.uint64("entry_size")
						if section.type == 2:
							self.symbol_table_section = section
						elif section.type == 11:
							self.dynamic_symbol_table_section = section
				except:
					# Section headers are not required to load an ELF, skip errors
					self.sections = self.tree.array(0, "sections")
					pass
				self.program_headers = self.tree.array(self.header.program_header_count, "program_headers")
				for i in range(0, self.header.program_header_count):
					header = self.program_headers[i]
					header.seek(self.header.program_header_offset + (i * 56))
					header.uint32("type")
					header.uint32("flags")
					header.uint64("offset")
					header.uint64("virtual_addr")
					header.uint64("physical_addr")
					header.uint64("file_size")
					header.uint64("memory_size")
					header.uint64("align")
				# Parse symbol tables
				self.symbols_by_name["_start"] = self.entry()
				self.symbols_by_addr[self.entry()] = "_start"
				try:
					if self.symbol_table_section:
						self.symbol_table = self.tree.array(self.symbol_table_section.size / 24, "Symbols", "symbols")
						self.parse_symbol_table_64(self.symbol_table, self.symbol_table_section, self.sections[self.symbol_table_section.link])
					if self.dynamic_symbol_table_section:
						self.dynamic_symbol_table = self.tree.array(self.dynamic_symbol_table_section.size / 24, "Symbols", "symbols")
						self.parse_symbol_table_64(self.dynamic_symbol_table, self.dynamic_symbol_table_section, self.sections[self.dynamic_symbol_table_section.link])
				except:
					# Skip errors in symbol table
					pass
				# Parse relocation tables
				self.plt = {}
				for section in self.sections:
					if section.type == 9:
						self.parse_reloc_64(section)
					elif section.type == 4:
						self.parse_reloca_64(section)
			self.tree.complete()
			self.valid = True
		except:
			self.valid = False
		if self.valid:
			self.data.add_callback(self)
	def read_string_table(self, strings, offset):
		end = strings.find("\x00", offset)
		return strings[offset:end]
	def parse_symbol_table_32(self, table, section, string_table):
		strings = self.data.read(string_table.offset, string_table.size)
		for i in range(0, section.size / 16):
			table[i].seek(section.offset + (i * 16))
			table[i].uint32("name_offset")
			table[i].uint32("value")
			table[i].uint32("size")
			table[i].uint8("info")
			table[i].uint8("other")
			table[i].uint16("section")
			table[i].name = self.read_string_table(strings, table[i].name_offset)
			if len(table[i].name) > 0:
				self.symbols_by_name[table[i].name] = table[i].value
				self.symbols_by_addr[table[i].value] = table[i].name
	def parse_symbol_table_64(self, table, section, string_table):
		strings = self.data.read(string_table.offset, string_table.size)
		for i in range(0, section.size / 24):
			table[i].seek(section.offset + (i * 24))
			table[i].uint32("name_offset")
			table[i].uint8("info")
			table[i].uint8("other")
			table[i].uint16("section")
			table[i].uint64("value")
			table[i].uint64("size")
			table[i].name = self.read_string_table(strings, table[i].name_offset)
			if len(table[i].name) > 0:
				self.symbols_by_name[table[i].name] = table[i].value
				self.symbols_by_addr[table[i].value] = table[i].name
	def parse_reloc_32(self, section):
		for i in range(0, section.size / 8):
			ofs = self.data.read_uint32(section.offset + (i * 8))
			info = self.data.read_uint32(section.offset + (i * 8) + 4)
			sym = info >> 8
			reloc_type = info & 0xff
			if reloc_type == 7: # R_386_JUMP_SLOT
				self.plt[ofs] = self.dynamic_symbol_table[sym].name
				self.symbols_by_name[self.decorate_plt_name(self.dynamic_symbol_table[sym].name)] = ofs
				self.symbols_by_addr[ofs] = self.decorate_plt_name(self.dynamic_symbol_table[sym].name)
	def parse_reloca_32(self, section):
		for i in range(0, section.size / 12):
			ofs = self.data.read_uint32(section.offset + (i * 12))
			info = self.data.read_uint32(section.offset + (i * 12) + 4)
			sym = info >> 8
			reloc_type = info & 0xff
			if reloc_type == 7: # R_386_JUMP_SLOT
				self.plt[ofs] = self.dynamic_symbol_table[sym].name
				self.symbols_by_name[self.decorate_plt_name(self.dynamic_symbol_table[sym].name)] = ofs
				self.symbols_by_addr[ofs] = self.decorate_plt_name(self.dynamic_symbol_table[sym].name)
	def parse_reloc_64(self, section):
		for i in range(0, section.size / 16):
			ofs = self.data.read_uint64(section.offset + (i * 16))
			info = self.data.read_uint64(section.offset + (i * 16) + 8)
			sym = info >> 32
			reloc_type = info & 0xff
			if reloc_type == 7: # R_X86_64_JUMP_SLOT
				self.plt[ofs] = self.dynamic_symbol_table[sym].name
				self.symbols_by_name[self.decorate_plt_name(self.dynamic_symbol_table[sym].name)] = ofs
				self.symbols_by_addr[ofs] = self.decorate_plt_name(self.dynamic_symbol_table[sym].name)
	def parse_reloca_64(self, section):
		for i in range(0, section.size / 24):
			ofs = self.data.read_uint64(section.offset + (i * 24))
			info = self.data.read_uint64(section.offset + (i * 24) + 8)
			sym = info >> 32
			reloc_type = info & 0xff
			if reloc_type == 7: # R_X86_64_JUMP_SLOT
				self.plt[ofs] = self.dynamic_symbol_table[sym].name
				self.symbols_by_name[self.decorate_plt_name(self.dynamic_symbol_table[sym].name)] = ofs
				self.symbols_by_addr[ofs] = self.decorate_plt_name(self.dynamic_symbol_table[sym].name)
	def read(self, ofs, len):
		result = ""
		while len > 0:
			cur = None
			for i in self.program_headers:
				if ((ofs >= i.virtual_addr) and (ofs < (i.virtual_addr + i.memory_size))) and (i.memory_size != 0):
					cur = i
			if cur == None:
				break
			prog_ofs = ofs - cur.virtual_addr
			mem_len = cur.memory_size - prog_ofs
			file_len = cur.file_size - prog_ofs
			if mem_len > len:
				mem_len = len
			if file_len > len:
				file_len = len
			if file_len <= 0:
				result += "\x00" * mem_len
				len -= mem_len
				ofs += mem_len
				continue
			result += self.data.read(cur.offset + prog_ofs, file_len)
			len -= file_len
			ofs += file_len
		return result
	def next_valid_addr(self, ofs):
		result = -1
		for i in self.program_headers:
			if (i.virtual_addr >= ofs) and (i.memory_size != 0) and ((result == -1) or (i.virtual_addr < result)):
				result = i.virtual_addr
		return result
	def get_modification(self, ofs, len):
		result = []
		while len > 0:
			cur = None
			for i in self.program_headers:
				if ((ofs >= i.virtual_addr) and (ofs < (i.virtual_addr + i.memory_size))) and (i.memory_size != 0):
					cur = i
			if cur == None:
				break
			prog_ofs = ofs - cur.virtual_addr
			mem_len = cur.memory_size - prog_ofs
			file_len = cur.file_size - prog_ofs
			if mem_len > len:
				mem_len = len
			if file_len > len:
				file_len = len
			if file_len <= 0:


Please complete the code given below. 
/**
 * Copyright (C) 2001-2015 by RapidMiner and the contributors
 *
 * Complete list of developers available at our web site:
 *
 *      http://rapidminer.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/.
 */
package com.rapidminer.example.set;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import com.rapidminer.MacroHandler;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.AttributeTypeException;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.operator.nio.model.DataResultSet.ValueType;
import com.rapidminer.parameter.ParameterTypeTupel;
import com.rapidminer.tools.I18N;
import com.rapidminer.tools.Ontology;
import com.rapidminer.tools.Tools;
/**
 * The condition is fulfilled if the individual filters are fulfilled. This filter can be
 * constructed from several conditions of the type {@link CustomFilters} which either must all be
 * fulfilled (AND) or only one must be fulfilled (OR).
 *
 * @author Marco Boeck
 */
public class CustomFilter implements Condition {
	/**
	 * Enum for custom filters.
	 */
	public static enum CustomFilters {
		EQUALS_NUMERICAL("gui.comparator.numerical.equals", "eq", Ontology.NUMERICAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				// special case to handle missing values
				if (Double.isNaN(filter)) {
					return Double.isNaN(input);
				}
				return input == filter;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		NOT_EQUALS_NUMERICAL("gui.comparator.numerical.not_equals", "ne", Ontology.NUMERICAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				// special case to handle missing values
				if (Double.isNaN(input)) {
					return !Double.isNaN(filter);
				}
				return input != filter;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		LESS("gui.comparator.numerical.less", "lt", Ontology.NUMERICAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return input < filter;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		LESS_EQUALS("gui.comparator.numerical.less_equals", "le", Ontology.NUMERICAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return input <= filter;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		GREATER_EQUALS("gui.comparator.numerical.greater_equals", "ge", Ontology.NUMERICAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return input >= filter;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		GREATER("gui.comparator.numerical.greater", "gt", Ontology.NUMERICAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return input > filter;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		EQUALS_NOMINAL("gui.comparator.nominal.equals", "equals", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return input.equals(filter);
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		NOT_EQUALS_NOMINAL("gui.comparator.nominal.not_equals", "does_not_equal", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return !input.equals(filter);
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		IS_IN_NOMINAL("gui.comparator.nominal.is_in", "is_in", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				List<String> filterList = Tools.unescape(filter, ESCAPE_CHAR, new char[] { SEPERATOR_CHAR }, SEPERATOR_CHAR);
				for (String filterString : filterList) {
					if (input.equals(filterString)) {
						return true;
					}
				}
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		IS_NOT_IN_NOMINAL("gui.comparator.nominal.is_not_in", "is_not_in", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				List<String> filterList = Tools.unescape(filter, ESCAPE_CHAR, new char[] { SEPERATOR_CHAR }, SEPERATOR_CHAR);
				for (String filterString : filterList) {
					if (input.equals(filterString)) {
						return false;
					}
				}
				return true;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		CONTAINS("gui.comparator.nominal.contains", "contains", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return input.contains(filter);
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		NOT_CONTAINS("gui.comparator.nominal.not_contains", "does_not_contain", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return !input.contains(filter);
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		STARTS_WITH("gui.comparator.nominal.starts_with", "starts_with", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return input.startsWith(filter);
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		ENDS_WITH("gui.comparator.nominal.ends_with", "ends_with", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return input.endsWith(filter);
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		REGEX("gui.comparator.nominal.regex", "matches", Ontology.NOMINAL) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return input.matches(filter);
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return false;
			}
		},
		MISSING("gui.comparator.special.is_missing", "is_missing", -1) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return Double.isNaN(input);
			}
		},
		NOT_MISSING("gui.comparator.special.is_not_missing", "is_not_missing", -1) {
			@Override
			public boolean isNumericalConditionFulfilled(final double input, final double filter) {
				return false;
			}
			@Override
			public boolean isNominalConditionFulfilled(final String input, final String filter) {
				return false;
			}
			@Override
			public boolean isSpecialConditionFulfilled(final double input) {
				return !Double.isNaN(input);
			}
		};
		/** the symbol to seperate strings for IS_IN and IS_NOT_IN input */
		public static final char SEPERATOR_CHAR = ';';
		/** the symbol to escape seperator symbols in IS_IN and IS_NOT_IN input */
		public static final char ESCAPE_CHAR = '\\';
		/** the format string for date_time */
		public static final String DATE_TIME_FORMAT_STRING = "MM/dd/yyyy h:mm:ss a";
		/** the old (bugged) format string for date_time */
		public static final String DATE_TIME_FORMAT_STRING_OLD = "MM/dd/yy h:mm:ss a";
		/** the format string for date */
		public static final String DATE_FORMAT_STRING = "MM/dd/yyyy";
		/** the old (bugged) format string for date */
		public static final String DATE_FORMAT_STRING_OLD = "MM/dd/yy";
		/** the format string for time */
		public static final String TIME_FORMAT_STRING = "h:mm:ss a";
		// ThreadLocal because DateFormat is NOT threadsafe and creating a new DateFormat is
		// EXTREMELY expensive
		/** the format for date_time */
		private static final ThreadLocal<DateFormat> FORMAT_DATE_TIME = new ThreadLocal<DateFormat>() {
			@Override
			protected DateFormat initialValue() {
				return new SimpleDateFormat(DATE_TIME_FORMAT_STRING, Locale.ENGLISH);
			}
		};
		/** the old format for date_time */
		private static final ThreadLocal<DateFormat> FORMAT_DATE_TIME_OLD = new ThreadLocal<DateFormat>() {
			@Override
			protected DateFormat initialValue() {
				return new SimpleDateFormat(DATE_TIME_FORMAT_STRING_OLD, Locale.ENGLISH);
			}
		};
		// ThreadLocal because DateFormat is NOT threadsafe and creating a new DateFormat is
		// EXTREMELY expensive
		/** the format for date */
		private static final ThreadLocal<DateFormat> FORMAT_DATE = new ThreadLocal<DateFormat>() {
			@Override
			protected DateFormat initialValue() {
				return new SimpleDateFormat(DATE_FORMAT_STRING, Locale.ENGLISH);
			}
		};
		/** the old format for date */
		private static final ThreadLocal<DateFormat> FORMAT_DATE_OLD = new ThreadLocal<DateFormat>() {
			@Override
			protected DateFormat initialValue() {
				return new SimpleDateFormat(DATE_FORMAT_STRING_OLD, Locale.ENGLISH);
			}
		};
		// ThreadLocal because DateFormat is NOT threadsafe and creating a new DateFormat is
		// EXTREMELY expensive
		/** the format for time */
		private static final ThreadLocal<DateFormat> FORMAT_TIME = new ThreadLocal<DateFormat>() {
			@Override
			protected DateFormat initialValue() {
				return new SimpleDateFormat(TIME_FORMAT_STRING, Locale.ENGLISH);
			}
		};
		/** the label for this filter */
		private String label;
		/** the string representation for this filter */
		private String symbol;
		/** the help text for this filter */
		private String helptext;
		/** the valueType for this filter */
		private int valueType;
		/**
		 * Creates a new {@link CustomFilters} instance which is represented by the specified symbol
		 * and accepts the given {@link ValueType}.
		 *
		 * @param key
		 * @param symbol
		 * @param valueType
		 *            the applicable {@link Ontology#ATTRIBUTE_VALUE_TYPE}. If set to -1, denotes a
		 *            special filter which is not restricted to any value type
		 */
		private CustomFilters(final String key, final String symbol, final int valueType) {
			this.symbol = symbol;
			this.label = I18N.getMessage(I18N.getGUIBundle(), key + ".label");
			this.helptext = I18N.getMessage(I18N.getGUIBundle(), key + ".tip");
			this.valueType = valueType;
		}
		/**
		 * Returns the {@link String} label for this comparator.
		 *
		 * @return
		 */
		public String getLabel() {
			return label;
		}
		/**
		 * Returns the {@link String} representation for this comparator.
		 *
		 * @return
		 */
		public String getSymbol() {
			return symbol;
		}
		/**
		 * Returns the helptext for this comparator.
		 *
		 * @return
		 */
		public String getHelptext() {
			return helptext;
		}
		/**
		 * Returns <code>true</code> if this filter is applicable for numerical values;
		 * <code>false</code> otherwise.
		 *
		 * @return
		 */
		public boolean isNumericalFilter() {
			if (isSpecialFilter()) {
				return false;
			}
			if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NUMERICAL)) {
				return true;
			}
			return false;
		}
		/**
		 * Returns <code>true</code> if this filter is applicable for nominal values;
		 * <code>false</code> otherwise.
		 *
		 * @return
		 */
		public boolean isNominalFilter() {
			if (isSpecialFilter()) {
				return false;
			}
			if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NOMINAL)) {
				return true;
			}
			return false;
		}
		/**
		 * Returns <code>true</code> if this filter is a special filter (e.g. missing value filter);
		 * <code>false</code> otherwise. <br/>
		 * These filters are applicable for all attribute types.
		 *
		 * @return
		 */
		public boolean isSpecialFilter() {
			if (valueType == -1) {
				return true;
			}
			return false;
		}
		/**
		 * Returns <code>true</code> if the numerical condition for this filter is fulfilled for the
		 * given value. Returns always <code>false</code> if the condition is for nominal values
		 * only.
		 *
		 * @param input
		 * @param filterValue
		 * @return
		 */
		public abstract boolean isNumericalConditionFulfilled(double input, double filterValue);
		/**
		 * Returns <code>true</code> if the nominal condition for this filter is fulfilled for the
		 * given value. Returns always <code>false</code> if the condition is for numerical values
		 * only.
		 *
		 * @param input
		 * @param filterValue
		 * @return
		 */
		public abstract boolean isNominalConditionFulfilled(String input, String filterValue);
		/**
		 * Returns <code>true</code> if the special condition for this filter is fulfilled for the
		 * given value.
		 *
		 * @param input
		 * @return
		 */
		public abstract boolean isSpecialConditionFulfilled(double input);
		/**
		 * Returns the {@link CustomFilters} matching the given label {@link String}. If none can be
		 * found, returns <code>null</code>.
		 *
		 * @param label
		 * @return
		 */
		public static CustomFilters getByLabel(final String label) {
			for (CustomFilters filter : values()) {
				if (filter.getLabel().equals(label)) {
					return filter;
				}
			}
			return null;
		}
		/**
		 * Returns the {@link CustomFilters} matching the given symbol {@link String}. If none can
		 * be found, returns <code>null</code>.
		 *
		 * @param symbol
		 * @return
		 */
		public static CustomFilters getBySymbol(final String symbol) {
			for (CustomFilters filter : values()) {
				if (filter.getSymbol().equals(symbol)) {
					return filter;
				}
			}
			return null;
		}
		/**
		 * Returns a list of {@link CustomFilters}s for the given {@link ValueType}. Returns an
		 * empty list if no filter was found.
		 *
		 * @param valueType
		 * @return
		 */
		public static List<CustomFilters> getFiltersForValueType(final int valueType) {
			List<CustomFilters> list = new LinkedList<>();
			for (CustomFilters filter : values()) {
				if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NOMINAL)) {
					// only nominal filters
					if (filter.isSpecialFilter() || filter.isNominalFilter()) {
						list.add(filter);
					}
				} else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NUMERICAL)) {
					// only numerical filters
					if (filter.isSpecialFilter() || filter.isNumericalFilter()) {
						list.add(filter);
					}
				} else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.DATE_TIME)) {
					// only numerical filters
					if (filter.isSpecialFilter() || filter.isNumericalFilter()) {
						list.add(filter);
					}
				} else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.ATTRIBUTE_VALUE)) {
					// unknown value type right now, allow all filters
					list.add(filter);
				} else {
					// filter only defined for numerical or nominal or unknown
				}
			}
			return list;
		}
		/**
		 * Returns a {@link Date} parsed via the date {@link String} or <code>null</code> if the
		 * given string could not be parsed. Uses {@link Locale#ENGLISH}.
		 * <p>
		 * Not static because {@link DateFormat} is NOT threadsafe.
		 * </p>
		 *
		 * @see #FORMAT_DATE_TIME
		 * @param dateTimeString
		 * @return
		 */
		public Date parseDateTime(final String dateTimeString) {
			try {
				return FORMAT_DATE_TIME.get().parse(dateTimeString);
			} catch (ParseException e) {
				return null;
			}
		}
		/**
		 * Old parser for date_time.
		 *
		 * @param dateTimeString
		 * @return
		 */
		private Date parseDateTimeOld(final String dateTimeString) {
			try {
				return FORMAT_DATE_TIME_OLD.get().parse(dateTimeString);
			} catch (ParseException e) {
				return null;
			}
		}
		/**
		 * Returns a {@link Date} parsed via the date {@link String} or <code>null</code> if the
		 * given string could not be parsed. Uses {@link Locale#ENGLISH}.
		 * <p>
		 * Not static because {@link DateFormat} is NOT threadsafe.
		 * </p>
		 *
		 * @see #FORMAT_DATE
		 * @param dateString
		 * @return
		 */
		public Date parseDate(final String dateString) {
			try {
				return FORMAT_DATE.get().parse(dateString);
			} catch (ParseException e) {
				return null;
			}
		}
		/**
		 * Old parser for date.
		 *
		 * @param dateString
		 * @return
		 */
		private Date parseDateOld(final String dateString) {
			try {
				return FORMAT_DATE_OLD.get().parse(dateString);
			} catch (ParseException e) {
				return null;
			}
		}
		/**
		 * Returns a {@link Date} parsed via the date {@link String} or <code>null</code> if the
		 * given string could not be parsed. Uses {@link Locale#ENGLISH}.
		 * <p>
		 * Not static because {@link DateFormat} is NOT threadsafe.
		 * </p>
		 *
		 * @see #FORMAT_TIME
		 * @param timeString
		 * @return
		 */
		public Date parseTime(final String timeString) {
			try {
				return FORMAT_TIME.get().parse(timeString);
			} catch (ParseException e) {
				return null;
			}
		}
		/**
		 * Returns a {@link String} formatted from the {@link Date}. Uses {@link Locale#ENGLISH}.
		 * <p>
		 * Not static because {@link DateFormat} is NOT threadsafe.
		 * </p>
		 *
		 * @see #FORMAT_TIME
		 * @param dateTime
		 * @return
		 */
		public String formatDateTime(final Date dateTime) {
			if (dateTime == null) {
				throw new IllegalArgumentException("dateTime must not be null!");
			}
			return FORMAT_DATE_TIME.get().format(dateTime);
		}
		/**
		 * Old format for date_time.
		 *
		 * @param dateTime
		 * @return
		 */
		public String formatDateTimeOld(final Date dateTime) {
			if (dateTime == null) {
				throw new IllegalArgumentException("dateTime must not be null!");
			}
			return FORMAT_DATE_TIME_OLD.get().format(dateTime);
		}
		/**
		 * Returns a {@link String} formatted from the {@link Date}. Uses {@link Locale#ENGLISH}.
		 * <p>
		 * Not static because {@link DateFormat} is NOT threadsafe.
		 * </p>
		 *
		 * @see #FORMAT_TIME
		 * @param date
		 * @return
		 */
		public String formatDate(final Date date) {
			if (date == null) {
				throw new IllegalArgumentException("date must not be null!");
			}
			return FORMAT_DATE.get().format(date);
		}
		/**
		 * Returns a {@link String} formatted from the {@link Date}. Uses {@link Locale#ENGLISH}.
		 * <p>
		 * Not static because {@link DateFormat} is NOT threadsafe.
		 * </p>
		 *
		 * @see #FORMAT_TIME
		 * @param time
		 * @return
		 */
		public String formatTime(final Date time) {
			if (time == null) {
				throw new IllegalArgumentException("time must not be null!");
			}
			return FORMAT_TIME.get().format(time);
		}
	}
	private static final long serialVersionUID = -1369785656210631292L;
	private static final String WHITESPACE = " ";
	private static final String BACKSLASH = "/";
	private static final int CONDITION_ARRAY_REQUIRED_SIZE = 2;
	private static final int CONDITION_ARRAY_CONDITION_INDEX = 1;
	private static final int CONDITION_TUPEL_REQUIRED_SIZE = 3;
	private static final int CONDITION_TUPEL_ATT_INDEX = 0;
	private static final int CONDITION_TUPEL_FILTER_INDEX = 1;
	private static final int CONDITION_TUPEL_VALUE_INDEX = 2;
	/** the list of all conditions */
	private List<String[]> conditions = new LinkedList<>();
	/**
	 * an array which indicates if for the ordered filter index the old (bugged) date parsing should
	 * be used
	 */
	private boolean[] conditionsOldDateFilter;
	/** the {@link MacroHandler}, will be used to resolve filter values, can be <code>null</code> */
	private MacroHandler macroHandler;
	private boolean fulfillAllConditions;
	/**
	 * Creates a new {@link CustomFilter} instance with the {@link CustomFilters} encoded in the
	 * {@link List} of {@link String} arrays. The {@link Boolean} parameter defines if either all
	 * conditions must be fulfilled or only one of them.
	 *
	 * @param exampleSet
	 * @param conditions
	 * @param fulfillAllConditions
	 * @param macroHandler
	 *            the macro handler which will be used to resolve macros for the filter value, can
	 *            be <code>null</code>
	 * @param version
	 *            can be used to force old behaviour. If not needed and current implementation is
	 *            desired, can be set to <code>null</code>
	 *
	 */
	public CustomFilter(final ExampleSet exampleSet, final List<String[]> conditions, final boolean fulfillAllConditions,
			final MacroHandler macroHandler) {
		if (conditions == null) {
			throw new IllegalArgumentException("typeList must not be null!");
		}
		conditionsOldDateFilter = new boolean[conditions.size()];
		// check if given conditions list is well formed and valid!
		int counter = 0;
		for (String[] conditionArray : conditions) {
			if (conditionArray.length != CONDITION_ARRAY_REQUIRED_SIZE) {
				throw new IllegalArgumentException("conditions must only consist of arrays of length 2!");
			}
			String condition = conditionArray[CONDITION_ARRAY_CONDITION_INDEX];
			String[] conditionTupel = ParameterTypeTupel.transformString2Tupel(condition);
			if (conditionTupel.length != CONDITION_TUPEL_REQUIRED_SIZE) {
				throw new IllegalArgumentException("Malformed condition tupels! Expected size 3 but was "
						+ conditionTupel.length);
			}
			String attName = conditionTupel[CONDITION_TUPEL_ATT_INDEX];
			Attribute att = exampleSet.getAttributes().get(attName);
			String filterSymbol = conditionTupel[CONDITION_TUPEL_FILTER_INDEX];
			CustomFilters filter = CustomFilters.getBySymbol(filterSymbol);
			String filterValue = conditionTupel[CONDITION_TUPEL_VALUE_INDEX];
			if (macroHandler != null) {
				this.macroHandler = macroHandler;
				filterValue = substituteMacros(filterValue, macroHandler);
			}
			if (filter == null) {
				throw new IllegalArgumentException(I18N.getMessageOrNull(I18N.getErrorBundle(),
						"custom_filters.filter_not_found", filterSymbol));
			}
			if (att == null) {
				throw new IllegalArgumentException(I18N.getMessageOrNull(I18N.getErrorBundle(),
						"custom_filters.attribute_not_found", attName));
			}
			// special checks for numerical filters
			if (filter.isNumericalFilter()) {
				// check if attribute is numerical
				if (att.isNominal()) {
					throw new AttributeTypeException(I18N.getMessageOrNull(I18N.getErrorBundle(),
							"custom_filters.numerical_comparator_type_invalid", filter.getLabel(), att.getName()));
				}
				if (att.isDateTime()) {
					// check if filter value works for date attribute
					if (filterValue == null || "".equals(filterValue) || !isStringValidDoubleValue(filter, filterValue, att)) {
						throw new IllegalArgumentException(I18N.getMessageOrNull(I18N.getErrorBundle(),
								"custom_filters.illegal_date_value", filterValue, att.getName()));
					}
				} else if (att.isNumerical()) {
					// check if filter value works for numerical attribute
					if (filterValue == null || "".equals(filterValue) || !isStringValidDoubleValue(filter, filterValue, att)) {
						throw new IllegalArgumentException(I18N.getMessageOrNull(I18N.getErrorBundle(),
								"custom_filters.illegal_numerical_value", filterValue, att.getName()));
					}
				}
				// keep compatibility with processes from versions prior to 6.0.004
				// only affects DATE and DATE_TIME filters
				int yearIndex = filterValue.lastIndexOf(BACKSLASH) + 1;
				int firstWhitespaceIndex = filterValue.indexOf(WHITESPACE);
				String yearString = null;
				if (yearIndex > 0 && firstWhitespaceIndex > 0 && yearIndex < firstWhitespaceIndex) {
					yearString = filterValue.substring(yearIndex, firstWhitespaceIndex);
				}
				// if true, the old (bugged) parsing will be used; otherwise the new yyyy parsing
				// will be used
				conditionsOldDateFilter[counter] = yearString != null && yearString.length() == 2;
			} else if (filter.isNominalFilter()) {
				if (!att.isNominal()) {
					throw new AttributeTypeException(I18N.getMessageOrNull(I18N.getErrorBundle(),
							"custom_filters.nominal_comparator_type_invalid", filter.getLabel(), att.getName()));
				}
			}
			counter++;
		}
		this.conditions = conditions;
		this.fulfillAllConditions = fulfillAllConditions;
	}
	/**
	 * The sole purpose of this constructor is to provide a constructor that matches the expected
	 * signature for the {@link ConditionedExampleSet} reflection invocation. However, this class
	 * cannot be instantiated by an ExampleSet and a String, so we <b>always</b> throw an
	 * {@link IllegalArgumentException} to signal this filter cannot be instantiated that way.
	 *
	 * @throws IllegalArgumentException
	 *             <b>ALWAYS THROWN!</b>
	 */
	@Deprecated
	public CustomFilter(final ExampleSet exampleSet, final String parameterString) throws IllegalArgumentException {
		throw new IllegalArgumentException("This condition cannot be instantiated this way!");
	}
	/**
	 * Since the condition cannot be altered after creation we can just return the condition object
	 * itself.
	 *
	 * @deprecated Conditions should not be able to be changed dynamically and hence there is no
	 *             need for a copy
	 */
	@Deprecated
	@Override
	public Condition duplicate() {
		return this;
	}
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		for (String[] array : conditions) {
			builder.append(Arrays.toString(array));
			builder.append(' ');
		}
		return builder.toString();
	}
	@Override
	public boolean conditionOk(final Example e) {
		boolean conditionsFulfilled = fulfillAllConditions ? true : false;
		int counter = 0;
		for (String[] conditionArray : conditions) {
			// we checked for malformed conditions in the constructor so no need to do it again
			String condition = conditionArray[CONDITION_ARRAY_CONDITION_INDEX];
			String[] conditionTupel = ParameterTypeTupel.transformString2Tupel(condition);
			String attName = conditionTupel[CONDITION_TUPEL_ATT_INDEX];
			Attribute att = e.getAttributes().get(attName);
			String filterSymbol = conditionTupel[CONDITION_TUPEL_FILTER_INDEX];
			CustomFilters filter = CustomFilters.getBySymbol(filterSymbol);
			String filterValue = conditionTupel[CONDITION_TUPEL_VALUE_INDEX];
			if (macroHandler != null) {
				filterValue = substituteMacros(filterValue, macroHandler);
			}
			// check if condition is fulfilled
			boolean fulfilled;
			if (filter.isSpecialFilter()) {
				fulfilled = filter.isSpecialConditionFulfilled(e.getValue(att));
			} else if (filter.isNominalFilter()) {
				fulfilled = filter.isNominalConditionFulfilled(e.getNominalValue(att), filterValue);
			} else {
				fulfilled = checkNumericalCondition(e, att, filter, filterSymbol, filterValue,
						conditionsOldDateFilter[counter]);
			}
			// store result
			if (fulfillAllConditions) {
				conditionsFulfilled &= fulfilled;
			} else {
				conditionsFulfilled |= fulfilled;
			}
			// shortcut for OR - one fulfilled condition is enough
			if (!fulfillAllConditions && conditionsFulfilled) {
				return true;
			}
			counter++;
		}
		return conditionsFulfilled;
	}
	/**
	 * Returns <code>true</code> if the given filter is fulfilled for the given value.
	 *
	 * @param e
	 * @param att
	 * @param filter
	 * @param filterSymbol
	 * @param filterValue
	 * @param oldBehavior
	 *            if <code>true</code>, old, bugged parsing with format dd/MM/yy will be used
	 * @return
	 */
	private boolean checkNumericalCondition(final Example e, final Attribute att, final CustomFilters filter,
			final String filterSymbol, final String filterValue, final boolean oldBehavior) {
		// special handling because we can have DATE_TIME, DATE and TIME strings in human readable
		// format here
		double doubleOriginalValue = e.getValue(att);
		double doubleFilterValue;
		try {
			doubleFilterValue = Double.parseDouble(filterValue);
		} catch (NumberFormatException e1) {
			// if we have a date we are losing precision - therefore we need to convert the original
			// value back and forth once so both lose the same amount of precision -
			// otherwise the filters will not work correctly
			if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.DATE)) {
				String formattedOriginal = filter.formatDate(new Date((long) doubleOriginalValue));
				doubleOriginalValue = filter.parseDate(formattedOriginal).getTime();
				// keep compatibility with processes from versions prior to 6.0.004
				if (oldBehavior) {
					// if year consists of 2 chars, use old (bugged) version
					doubleFilterValue = filter.parseDateOld(filterValue).getTime();
				} else {
					// new behavior
					doubleFilterValue = filter.parseDate(filterValue).getTime();
				}
			} else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.TIME)) {
				String formattedOriginal = filter.formatTime(new Date((long) doubleOriginalValue));
				doubleOriginalValue = filter.parseTime(formattedOriginal).getTime();
				doubleFilterValue = filter.parseTime(filterValue).getTime();
			} else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.DATE_TIME)) {
				String formattedOriginal = filter.formatDateTime(new Date((long) doubleOriginalValue));
				doubleOriginalValue = filter.parseDateTime(formattedOriginal).getTime();
				// keep compatibility with processes from versions prior to 6.0.004
				if (oldBehavior) {
					// if year consists of 2 chars, use old (bugged) version
					doubleFilterValue = filter.parseDateTimeOld(filterValue).getTime();
				} else {
					// new behavior
					doubleFilterValue = filter.parseDateTime(filterValue).getTime();
				}
			} else {
				// because we have checked the filters in the constructor, this is the only option
				// left
				// special handling for ? as missing value
				doubleFilterValue = Double.NaN;
			}
		}
		return filter.isNumericalConditionFulfilled(doubleOriginalValue, doubleFilterValue);
	}
	/**
	 * Tries to parse the given {@link String} to a {@link Double} and returns <code>true</code> if
	 * successful; <code>false</code> otherwise.
	 *
	 * @param value
	 * @param att
	 * @return
	 */
	private boolean isStringValidDoubleValue(final CustomFilters filter, final String value, final Attribute att) {
		try {
			Double.parseDouble(value);
		} catch (NumberFormatException e1) {
			// if we have a date we are losing precision - therefore we need to convert the original
			// value back and forth once so both lose the same amount of precision -
			// otherwise the filters will not work correctly
			if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.DATE)) {
				if (filter.parseDate(value) == null) {
					return false;
				}
			} else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.TIME)) {
				if (filter.parseTime(value) == null) {
					return false;
				}
			} else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.DATE_TIME)) {
				if (filter.parseDateTime(value) == null) {
					return false;
				}
			} else {
				if ("?".equals(value)) {
					// special handling for ? as missing value
					return true;
				} else {
					// all parsing tries failed
					return false;
				}
			}
		}
		return true;
	}
	/**
	 * Tries to substitute macros with their real value.
	 *
	 * @param value
	 * @param macroHandler
	 * @return
	 */
	private static String substituteMacros(String value, final MacroHandler macroHandler) {
		int startIndex = value.indexOf("%{");
		if (startIndex == -1) {
			return value;
		}
		try {


Please complete the code given below. 
/*
 * Copyright 2008-2020 Ping Identity Corporation
 * All Rights Reserved.
 */
/*
 * Copyright 2008-2020 Ping Identity Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Copyright (C) 2008-2020 Ping Identity Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>.
 */
package com.unboundid.ldap.sdk.unboundidds.controls;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import com.unboundid.asn1.ASN1Boolean;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.asn1.ASN1Sequence;
import com.unboundid.ldap.sdk.Control;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.Debug;
import com.unboundid.util.NotMutable;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;
/**
 * This class provides an implementation of an LDAP control that can be included
 * in a bind request to request that the Directory Server return the
 * authentication and authorization entries for the user that authenticated.
 * <BR>
 * <BLOCKQUOTE>
 *   <B>NOTE:</B>  This class, and other classes within the
 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
 *   supported for use against Ping Identity, UnboundID, and
 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
 *   for proprietary functionality or for external specifications that are not
 *   considered stable or mature enough to be guaranteed to work in an
 *   interoperable way with other types of LDAP servers.
 * </BLOCKQUOTE>
 * <BR>
 * The value of this control may be absent, but if it is present then will be
 * encoded as follows:
 * <PRE>
 *   GetAuthorizationEntryRequest ::= SEQUENCE {
 *        includeAuthNEntry     [0] BOOLEAN DEFAULT TRUE,
 *        includeAuthZEntry     [1] BOOLEAN DEFAULT TRUE,
 *        attributes            [2] AttributeSelection OPTIONAL }
 * </PRE>
 * <BR><BR>
 * <H2>Example</H2>
 * The following example demonstrates the process for processing a bind
 * operation using the get authorization entry request control to return all
 * user attributes in both the authentication and authorization entries:
 * <PRE>
 * ReadOnlyEntry authNEntry = null;
 * ReadOnlyEntry authZEntry = null;
 *
 * BindRequest bindRequest = new SimpleBindRequest(
 *      "uid=john.doe,ou=People,dc=example,dc=com", "password",
 *      new GetAuthorizationEntryRequestControl());
 *
 * BindResult bindResult = connection.bind(bindRequest);
 * GetAuthorizationEntryResponseControl c =
 *      GetAuthorizationEntryResponseControl.get(bindResult);
 * if (c != null)
 * {
 *   authNEntry = c.getAuthNEntry();
 *   authZEntry = c.getAuthZEntry();
 * }
 * </PRE>
 */
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class GetAuthorizationEntryRequestControl
       extends Control
{
  /**
   * The OID (1.3.6.1.4.1.30221.2.5.6) for the get authorization entry request
   * control.
   */
  @NotNull public static final String GET_AUTHORIZATION_ENTRY_REQUEST_OID =
       "1.3.6.1.4.1.30221.2.5.6";
  /**
   * The BER type for the {@code includeAuthNEntry} element.
   */
  private static final byte TYPE_INCLUDE_AUTHN_ENTRY = (byte) 0x80;
  /**
   * The BER type for the {@code includeAuthZEntry} element.
   */
  private static final byte TYPE_INCLUDE_AUTHZ_ENTRY = (byte) 0x81;
  /**
   * The BER type for the {@code attributes} element.
   */
  private static final byte TYPE_ATTRIBUTES = (byte) 0xA2;
  /**
   * The serial version UID for this serializable class.
   */
  private static final long serialVersionUID = -5540345171260624216L;
  // Indicates whether to include the authentication entry in the response.
  private final boolean includeAuthNEntry;
  // Indicates whether to include the authorization entry in the response.
  private final boolean includeAuthZEntry;
  // The list of attributes to include in entries that are returned.
  @NotNull private final List<String> attributes;
  /**
   * Creates a new get authorization entry request control that will request all
   * user attributes in both the authentication and authorization entries.  It
   * will not be marked critical.
   */
  public GetAuthorizationEntryRequestControl()
  {
    this(false, true, true, (List<String>) null);
  }
  /**
   * Creates a new get authorization entry request control with the provided
   * information.
   *
   * @param  includeAuthNEntry  Indicates whether to include the authentication
   *                            entry in the response.
   * @param  includeAuthZEntry  Indicates whether to include the authorization
   *                            entry in the response.
   * @param  attributes         The attributes to include in the entries in the
   *                            response.  It may be empty or {@code null} to
   *                            request all user attributes.
   */
  public GetAuthorizationEntryRequestControl(final boolean includeAuthNEntry,
              final boolean includeAuthZEntry,
              @Nullable final String... attributes)
  {
    this(false, includeAuthNEntry, includeAuthZEntry,
         (attributes == null) ? null : Arrays.asList(attributes));
  }
  /**
   * Creates a new get authorization entry request control with the provided
   * information.
   *
   * @param  includeAuthNEntry  Indicates whether to include the authentication
   *                            entry in the response.
   * @param  includeAuthZEntry  Indicates whether to include the authorization
   *                            entry in the response.
   * @param  attributes         The attributes to include in the entries in the
   *                            response.  It may be empty or {@code null} to
   *                            request all user attributes.
   */
  public GetAuthorizationEntryRequestControl(final boolean includeAuthNEntry,
              final boolean includeAuthZEntry,
              @Nullable final List<String> attributes)
  {
    this(false, includeAuthNEntry, includeAuthZEntry, attributes);
  }
  /**
   * Creates a new get authorization entry request control with the provided
   * information.
   *
   * @param  isCritical         Indicates whether the control should be marked
   *                            critical.
   * @param  includeAuthNEntry  Indicates whether to include the authentication
   *                            entry in the response.
   * @param  includeAuthZEntry  Indicates whether to include the authorization
   *                            entry in the response.
   * @param  attributes         The attributes to include in the entries in the
   *                            response.  It may be empty or {@code null} to
   *                            request all user attributes.
   */
  public GetAuthorizationEntryRequestControl(final boolean isCritical,
              final boolean includeAuthNEntry,
              final boolean includeAuthZEntry,
              @Nullable final String... attributes)
  {
    this(isCritical, includeAuthNEntry, includeAuthZEntry,
         (attributes == null) ? null : Arrays.asList(attributes));
  }
  /**
   * Creates a new get authorization entry request control with the provided
   * information.
   *
   * @param  isCritical         Indicates whether the control should be marked
   *                            critical.
   * @param  includeAuthNEntry  Indicates whether to include the authentication
   *                            entry in the response.
   * @param  includeAuthZEntry  Indicates whether to include the authorization
   *                            entry in the response.
   * @param  attributes         The attributes to include in the entries in the
   *                            response.  It may be empty or {@code null} to
   *                            request all user attributes.
   */
  public GetAuthorizationEntryRequestControl(final boolean isCritical,
              final boolean includeAuthNEntry,
              final boolean includeAuthZEntry,
              @Nullable final List<String> attributes)
  {
    super(GET_AUTHORIZATION_ENTRY_REQUEST_OID, isCritical,
          encodeValue(includeAuthNEntry, includeAuthZEntry, attributes));
    this.includeAuthNEntry = includeAuthNEntry;
    this.includeAuthZEntry = includeAuthZEntry;
    if ((attributes == null) || attributes.isEmpty())
    {
      this.attributes = Collections.emptyList();
    }
    else
    {
      this.attributes =
           Collections.unmodifiableList(new ArrayList<>(attributes));
    }
  }
  /**
   * Creates a new get authorization entry request control which is decoded from
   * the provided generic control.
   *
   * @param  control  The generic control to decode as a get authorization entry
   *                  request control.
   *
   * @throws  LDAPException  If the provided control cannot be decoded as a get
   *                         authorization entry request control.
   */
  public GetAuthorizationEntryRequestControl(@NotNull final Control control)
         throws LDAPException
  {
    super(control);
    final ASN1OctetString value = control.getValue();
    if (value == null)
    {
      includeAuthNEntry = true;
      includeAuthZEntry = true;
      attributes        = Collections.emptyList();
      return;
    }
    try
    {
      final ArrayList<String> attrs = new ArrayList<>(20);
      boolean includeAuthN = true;
      boolean includeAuthZ = true;
      final ASN1Element element = ASN1Element.decode(value.getValue());
      for (final ASN1Element e :
           ASN1Sequence.decodeAsSequence(element).elements())
      {
        switch (e.getType())
        {
          case TYPE_INCLUDE_AUTHN_ENTRY:
            includeAuthN = ASN1Boolean.decodeAsBoolean(e).booleanValue();
            break;
          case TYPE_INCLUDE_AUTHZ_ENTRY:
            includeAuthZ = ASN1Boolean.decodeAsBoolean(e).booleanValue();
            break;
          case TYPE_ATTRIBUTES:
            for (final ASN1Element ae :
                 ASN1Sequence.decodeAsSequence(e).elements())
            {
              attrs.add(ASN1OctetString.decodeAsOctetString(ae).stringValue());
            }
            break;
          default:
            throw new LDAPException(ResultCode.DECODING_ERROR,
                 ERR_GET_AUTHORIZATION_ENTRY_REQUEST_INVALID_SEQUENCE_ELEMENT.
                      get(StaticUtils.toHex(e.getType())));
        }
      }
      includeAuthNEntry = includeAuthN;
      includeAuthZEntry = includeAuthZ;
      attributes        = attrs;
    }
    catch (final LDAPException le)
    {
      throw le;
    }
    catch (final Exception e)
    {
      Debug.debugException(e);
      throw new LDAPException(ResultCode.DECODING_ERROR,
           ERR_GET_AUTHORIZATION_ENTRY_REQUEST_CANNOT_DECODE_VALUE.get(
                StaticUtils.getExceptionMessage(e)),
           e);
    }
  }
  /**
   * Encodes the provided information as appropriate for use as the value of
   * this control.
   *
   * @param  includeAuthNEntry  Indicates whether to include the authentication
   *                            entry in the response.
   * @param  includeAuthZEntry  Indicates whether to include the authorization
   *                            entry in the response.
   * @param  attributes         The attributes to include in the entries in the
   *                            response.  It may be empty or {@code null} to
   *                            request all user attributes.
   *
   * @return  An ASN.1 octet string appropriately encoded for use as the control
   *          value, or {@code null} if no value is needed.
   */
  @Nullable()
  private static ASN1OctetString encodeValue(final boolean includeAuthNEntry,
                      final boolean includeAuthZEntry,
                      @Nullable final List<String> attributes)
  {
    if (includeAuthNEntry && includeAuthZEntry &&
        ((attributes == null) || attributes.isEmpty()))
    {
      return null;
    }
    final ArrayList<ASN1Element> elements = new ArrayList<>(3);
    if (! includeAuthNEntry)
    {


Please complete the code given below. 
//#############################################################################
//#                                                                           #
//#  Copyright (C) <2015>  <IMS MAXIMS>                                       #
//#                                                                           #
//#  This program is free software: you can redistribute it and/or modify     #
//#  it under the terms of the GNU Affero General Public License as           #
//#  published by the Free Software Foundation, either version 3 of the       #
//#  License, or (at your option) any later version.                          # 
//#                                                                           #
//#  This program is distributed in the hope that it will be useful,          #
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of           #
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            #
//#  GNU Affero General Public License for more details.                      #
//#                                                                           #
//#  You should have received a copy of the GNU Affero General Public License #
//#  along with this program.  If not, see <http://www.gnu.org/licenses/>.    #
//#                                                                           #
//#  IMS MAXIMS provides absolutely NO GUARANTEE OF THE CLINICAL SAFTEY of    #
//#  this program.  Users of this software do so entirely at their own risk.  #
//#  IMS MAXIMS only ensures the Clinical Safety of unaltered run-time        #
//#  software that it builds, deploys and maintains.                          #
//#                                                                           #
//#############################################################################
//#EOH
// This code was generated by Barbara Worwood using IMS Development Environment (version 1.80 build 5589.25814)
// Copyright (C) 1995-2015 IMS MAXIMS. All rights reserved.
// WARNING: DO NOT MODIFY the content of this file
package ims.nursing.vo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import ims.framework.enumerations.SortOrder;
public class InvasiveDeviceSearchCriteriaVoCollection extends ims.vo.ValueObjectCollection implements ims.vo.ImsCloneable, Iterable<InvasiveDeviceSearchCriteriaVo>
{
	private static final long serialVersionUID = 1L;
	private ArrayList<InvasiveDeviceSearchCriteriaVo> col = new ArrayList<InvasiveDeviceSearchCriteriaVo>();
	public String getBoClassName()
	{
		return null;
	}
	public boolean add(InvasiveDeviceSearchCriteriaVo value)
	{
		if(value == null)
			return false;
		if(this.col.indexOf(value) < 0)
		{
			return this.col.add(value);
		}
		return false;
	}
	public boolean add(int index, InvasiveDeviceSearchCriteriaVo value)
	{
		if(value == null)
			return false;
		if(this.col.indexOf(value) < 0)
		{
			this.col.add(index, value);
			return true;
		}
		return false;
	}
	public void clear()
	{
		this.col.clear();
	}
	public void remove(int index)
	{
		this.col.remove(index);
	}
	public int size()
	{
		return this.col.size();
	}
	public int indexOf(InvasiveDeviceSearchCriteriaVo instance)
	{
		return col.indexOf(instance);
	}
	public InvasiveDeviceSearchCriteriaVo get(int index)
	{
		return this.col.get(index);
	}
	public boolean set(int index, InvasiveDeviceSearchCriteriaVo value)
	{
		if(value == null)
			return false;
		this.col.set(index, value);
		return true;
	}
	public void remove(InvasiveDeviceSearchCriteriaVo instance)
	{
		if(instance != null)
		{
			int index = indexOf(instance);
			if(index >= 0)
				remove(index);
		}
	}
	public boolean contains(InvasiveDeviceSearchCriteriaVo instance)
	{
		return indexOf(instance) >= 0;
	}
	public Object clone()
	{
		InvasiveDeviceSearchCriteriaVoCollection clone = new InvasiveDeviceSearchCriteriaVoCollection();
		
		for(int x = 0; x < this.col.size(); x++)
		{
			if(this.col.get(x) != null)
				clone.col.add((InvasiveDeviceSearchCriteriaVo)this.col.get(x).clone());
			else
				clone.col.add(null);
		}
		
		return clone;
	}
	public boolean isValidated()
	{
		for(int x = 0; x < col.size(); x++)
			if(!this.col.get(x).isValidated())
				return false;
		return true;
	}
	public String[] validate()
	{
		return validate(null);
	}
	public String[] validate(String[] existingErrors)
	{
		if(col.size() == 0)
			return null;
		java.util.ArrayList<String> listOfErrors = new java.util.ArrayList<String>();
		if(existingErrors != null)
		{
			for(int x = 0; x < existingErrors.length; x++)
			{
				listOfErrors.add(existingErrors[x]);
			}
		}
		for(int x = 0; x < col.size(); x++)
		{
			String[] listOfOtherErrors = this.col.get(x).validate();
			if(listOfOtherErrors != null)
			{
				for(int y = 0; y < listOfOtherErrors.length; y++)
				{
					listOfErrors.add(listOfOtherErrors[y]);
				}
			}
		}
		
		int errorCount = listOfErrors.size();
		if(errorCount == 0)
			return null;
		String[] result = new String[errorCount];
		for(int x = 0; x < errorCount; x++)
			result[x] = (String)listOfErrors.get(x);
		return result;
	}
	public InvasiveDeviceSearchCriteriaVoCollection sort()
	{
		return sort(SortOrder.ASCENDING);
	}
	public InvasiveDeviceSearchCriteriaVoCollection sort(boolean caseInsensitive)
	{
		return sort(SortOrder.ASCENDING, caseInsensitive);
	}
	public InvasiveDeviceSearchCriteriaVoCollection sort(SortOrder order)
	{
		return sort(new InvasiveDeviceSearchCriteriaVoComparator(order));
	}
	public InvasiveDeviceSearchCriteriaVoCollection sort(SortOrder order, boolean caseInsensitive)
	{
		return sort(new InvasiveDeviceSearchCriteriaVoComparator(order, caseInsensitive));
	}
	@SuppressWarnings("unchecked")
	public InvasiveDeviceSearchCriteriaVoCollection sort(Comparator comparator)
	{
		Collections.sort(col, comparator);
		return this;
	}
	public InvasiveDeviceSearchCriteriaVo[] toArray()
	{
		InvasiveDeviceSearchCriteriaVo[] arr = new InvasiveDeviceSearchCriteriaVo[col.size()];
		col.toArray(arr);
		return arr;
	}
	public Iterator<InvasiveDeviceSearchCriteriaVo> iterator()
	{
		return col.iterator();
	}
	@Override
	protected ArrayList getTypedCollection()
	{
		return col;
	}
	private class InvasiveDeviceSearchCriteriaVoComparator implements Comparator
	{
		private int direction = 1;
		private boolean caseInsensitive = true;
		public InvasiveDeviceSearchCriteriaVoComparator()
		{
			this(SortOrder.ASCENDING);
		}
		public InvasiveDeviceSearchCriteriaVoComparator(SortOrder order)
		{
			if (order == SortOrder.DESCENDING)
			{
				direction = -1;
			}
		}
		public InvasiveDeviceSearchCriteriaVoComparator(SortOrder order, boolean caseInsensitive)
		{
			if (order == SortOrder.DESCENDING)
			{
				direction = -1;
			}
			this.caseInsensitive = caseInsensitive;
		}
		public int compare(Object obj1, Object obj2)
		{
			InvasiveDeviceSearchCriteriaVo voObj1 = (InvasiveDeviceSearchCriteriaVo)obj1;
			InvasiveDeviceSearchCriteriaVo voObj2 = (InvasiveDeviceSearchCriteriaVo)obj2;
			return direction*(voObj1.compareTo(voObj2, this.caseInsensitive));
		}
		public boolean equals(Object obj)
		{
			return false;
		}
	}
	public ims.nursing.vo.beans.InvasiveDeviceSearchCriteriaVoBean[] getBeanCollection()
	{
		return getBeanCollectionArray();
	}
	public ims.nursing.vo.beans.InvasiveDeviceSearchCriteriaVoBean[] getBeanCollectionArray()
	{
		ims.nursing.vo.beans.InvasiveDeviceSearchCriteriaVoBean[] result = new ims.nursing.vo.beans.InvasiveDeviceSearchCriteriaVoBean[col.size()];
		for(int i = 0; i < col.size(); i++)
		{
			InvasiveDeviceSearchCriteriaVo vo = ((InvasiveDeviceSearchCriteriaVo)col.get(i));
			result[i] = (ims.nursing.vo.beans.InvasiveDeviceSearchCriteriaVoBean)vo.getBean();
		}
		return result;
	}
	public static InvasiveDeviceSearchCriteriaVoCollection buildFromBeanCollection(java.util.Collection beans)
	{
		InvasiveDeviceSearchCriteriaVoCollection coll = new InvasiveDeviceSearchCriteriaVoCollection();
		if(beans == null)
			return coll;
		java.util.Iterator iter = beans.iterator();
		while (iter.hasNext())
		{
			coll.add(((ims.nursing.vo.beans.InvasiveDeviceSearchCriteriaVoBean)iter.next()).buildVo());
		}
		return coll;
	}
	public static InvasiveDeviceSearchCriteriaVoCollection buildFromBeanCollection(ims.nursing.vo.beans.InvasiveDeviceSearchCriteriaVoBean[] beans)
	{
		InvasiveDeviceSearchCriteriaVoCollection coll = new InvasiveDeviceSearchCriteriaVoCollection();


Please complete the code given below. 
package com.idevicesinc.sweetblue;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import android.content.Context;
import android.content.SharedPreferences;
import com.idevicesinc.sweetblue.utils.EmptyIterator;
import com.idevicesinc.sweetblue.utils.State;
class P_DiskOptionsManager
{
	private static final int ACCESS_MODE = Context.MODE_PRIVATE;
	//--- DRK > Just adding some salt to these to mitigate any possible conflict.
	private static enum E_Namespace
	{
		LAST_DISCONNECT("sweetblue_16l@{&a}"),
		NEEDS_BONDING("sweetblue_p59=F%k"),
		DEVICE_NAME("sweetblue_qurhzpoc");
		private final String m_key;
		private E_Namespace(final String key)
		{
			m_key = key;
		}
		public String key()
		{
			return m_key;
		}
	}
	
	private final Context m_context;
	
	private final HashMap<String, Integer> m_inMemoryDb_lastDisconnect = new HashMap<String, Integer>();
	private final HashMap<String, Boolean> m_inMemoryDb_needsBonding = new HashMap<String, Boolean>();
	private final HashMap<String, String> m_inMemoryDb_name = new HashMap<String, String>();
	private final HashMap[] m_inMemoryDbs = new HashMap[E_Namespace.values().length];
	
	public P_DiskOptionsManager(Context context)
	{
		m_context = context;
		m_inMemoryDbs[E_Namespace.LAST_DISCONNECT.ordinal()] = m_inMemoryDb_lastDisconnect;
		m_inMemoryDbs[E_Namespace.NEEDS_BONDING.ordinal()] = m_inMemoryDb_needsBonding;
		m_inMemoryDbs[E_Namespace.DEVICE_NAME.ordinal()] = m_inMemoryDb_name;
		final E_Namespace[] values = E_Namespace.values();
		for( int i = 0; i < values.length; i++ )
		{
			Object ith = m_inMemoryDbs[i];
			if( ith == null )
			{
				throw new Error("Expected in-memory DB to be not null");
			}
		}
	}
	
	private SharedPreferences prefs(E_Namespace namespace)
	{
		final SharedPreferences prefs = m_context.getSharedPreferences(namespace.key(), ACCESS_MODE);
		
		return prefs;
	}
	
	public void saveLastDisconnect(final String mac, final State.ChangeIntent changeIntent, final boolean hitDisk)
	{
		final int diskValue = State.ChangeIntent.toDiskValue(changeIntent);
		m_inMemoryDb_lastDisconnect.put(mac, diskValue);
		
		if( !hitDisk )  return;
		prefs(E_Namespace.LAST_DISCONNECT).edit().putInt(mac, diskValue).commit();
	}
	
	public State.ChangeIntent loadLastDisconnect(final String mac, final boolean hitDisk)
	{
		final Integer value_memory = m_inMemoryDb_lastDisconnect.get(mac);
		
		if( value_memory != null )
		{
			final State.ChangeIntent lastDisconnect_memory = State.ChangeIntent.fromDiskValue(value_memory);
			
			return lastDisconnect_memory;
		}
		
		if( !hitDisk )  return State.ChangeIntent.NULL;
		
		final SharedPreferences prefs = prefs(E_Namespace.LAST_DISCONNECT);
		
		final int value_disk = prefs.getInt(mac, State.ChangeIntent.NULL.toDiskValue());
		
		final State.ChangeIntent lastDisconnect = State.ChangeIntent.fromDiskValue(value_disk);
		
		return lastDisconnect;
	}
	
	public void saveNeedsBonding(final String mac, final boolean hitDisk)
	{
		m_inMemoryDb_needsBonding.put(mac, true);
		
		if( !hitDisk )  return;
		
		prefs(E_Namespace.NEEDS_BONDING).edit().putBoolean(mac, true).commit();
	}
	
	public boolean loadNeedsBonding(final String mac, final boolean hitDisk)
	{
		final Boolean value_memory = m_inMemoryDb_needsBonding.get(mac);
		
		if( value_memory != null )
		{
			return value_memory;
		}
		
		if( !hitDisk )  return false;
		
		final SharedPreferences prefs = prefs(E_Namespace.NEEDS_BONDING);
		
		final boolean value_disk = prefs.getBoolean(mac, false);
		
		return value_disk;
	}
	public void saveName(final String mac, final String name, final boolean hitDisk)
	{
		final String name_override = name != null ? name : "";
		m_inMemoryDb_name.put(mac, name_override);
		if( !hitDisk )  return;
		prefs(E_Namespace.DEVICE_NAME).edit().putString(mac, name_override).commit();
	}
	public String loadName(final String mac, final boolean hitDisk)
	{
		final String value_memory = m_inMemoryDb_name.get(mac);
		if( value_memory != null )
		{
			return value_memory;
		}
		if( !hitDisk )  return null;
		final SharedPreferences prefs = prefs(E_Namespace.DEVICE_NAME);
		final String value_disk = prefs.getString(mac, null);
		return value_disk;
	}
	void clear()
	{
		final E_Namespace[] values = E_Namespace.values();
		for( int i = 0; i < values.length; i++ )
		{
			final SharedPreferences prefs = prefs(values[i]);
			prefs.edit().clear().commit();
			final HashMap ith = m_inMemoryDbs[i];
			if( ith != null )
			{
				ith.clear();
			}
		}
	}
	void clearName(final String macAddress)
	{
		final E_Namespace namespace = E_Namespace.DEVICE_NAME;
		clearNamespace(macAddress, namespace);
	}
	private void clearNamespace(final String macAddress, final E_Namespace namespace)
	{
		final int ordinal = namespace.ordinal();
		final SharedPreferences prefs = prefs(namespace);
		prefs.edit().remove(macAddress).commit();
		final HashMap ith = m_inMemoryDbs[ordinal];
		if( ith != null )
		{
			ith.remove(macAddress);
		}
	}
	void clear(final String macAddress)
	{
		final E_Namespace[] values = E_Namespace.values();
		for( int i = 0; i < values.length; i++ )
		{
			clearNamespace(macAddress, values[i]);
		}
	}
	Iterator<String> getPreviouslyConnectedDevices()
	{
		final SharedPreferences prefs = prefs(E_Namespace.LAST_DISCONNECT);
		Map<String, ?> map = prefs.getAll();
		if( map != null )
		{
			return map.keySet().iterator();
		}
		else
		{


Please complete the code given below. 
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ServiceStack.ServiceHost;
using ServiceStack.ServiceModel.Serialization;
using ServiceStack.Text;
namespace ServiceStack.Common.Web
{
    public class HttpResponseFilter : IContentTypeFilter
    {
        private static readonly UTF8Encoding UTF8EncodingWithoutBom = new UTF8Encoding(false);
        public static HttpResponseFilter Instance = new HttpResponseFilter();
        public Dictionary<string, StreamSerializerDelegate> ContentTypeSerializers
            = new Dictionary<string, StreamSerializerDelegate>();
        public Dictionary<string, ResponseSerializerDelegate> ContentTypeResponseSerializers
            = new Dictionary<string, ResponseSerializerDelegate>();
        public Dictionary<string, StreamDeserializerDelegate> ContentTypeDeserializers
            = new Dictionary<string, StreamDeserializerDelegate>();
        public HttpResponseFilter()
        {
            this.ContentTypeFormats = new Dictionary<string, string>();
        }
        public void ClearCustomFilters()
        {
            this.ContentTypeFormats = new Dictionary<string, string>();
            this.ContentTypeSerializers = new Dictionary<string, StreamSerializerDelegate>();
            this.ContentTypeDeserializers = new Dictionary<string, StreamDeserializerDelegate>();
        }
        public Dictionary<string, string> ContentTypeFormats { get; set; }
        public void Register(string contentType, StreamSerializerDelegate streamSerializer, StreamDeserializerDelegate streamDeserializer)
        {
            if (contentType.IsNullOrEmpty())
                throw new ArgumentNullException("contentType");
            var parts = contentType.Split('/');
            var format = parts[parts.Length - 1];
            this.ContentTypeFormats[format] = contentType;
            SetContentTypeSerializer(contentType, streamSerializer);
            SetContentTypeDeserializer(contentType, streamDeserializer);
        }
        public void Register(string contentType, ResponseSerializerDelegate responseSerializer,
                             StreamDeserializerDelegate streamDeserializer)
        {
            if (contentType.IsNullOrEmpty())
                throw new ArgumentNullException("contentType");
            var parts = contentType.Split('/');
            var format = parts[parts.Length - 1];
            this.ContentTypeFormats[format] = contentType;
            this.ContentTypeResponseSerializers[contentType] = responseSerializer;
            SetContentTypeDeserializer(contentType, streamDeserializer);
        }
        public void SetContentTypeSerializer(string contentType, StreamSerializerDelegate streamSerializer)
        {
            this.ContentTypeSerializers[contentType] = streamSerializer;
        }
        public void SetContentTypeDeserializer(string contentType, StreamDeserializerDelegate streamDeserializer)
        {
            this.ContentTypeDeserializers[contentType] = streamDeserializer;
        }
        public string Serialize(string contentType, object response)
        {
            switch (contentType)
            {
                case ContentType.Xml:
                    return XmlSerializer.SerializeToString(response);
                case ContentType.Json:
                    return JsonDataContractSerializer.Instance.SerializeToString(response);
                case ContentType.Jsv:
                    return TypeSerializer.SerializeToString(response);
                default:
                    throw new NotSupportedException("ContentType not supported: " + contentType);
            }
        }
        public byte[] SerializeToBytes(IRequestContext requestContext, object response)
        {
            var contentType = requestContext.ResponseContentType;
            StreamSerializerDelegate responseStreamWriter;
            if (this.ContentTypeSerializers.TryGetValue(contentType, out responseStreamWriter) ||
                this.ContentTypeSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseStreamWriter))
            {
                using (var ms = new MemoryStream())
                {
                    responseStreamWriter(requestContext, response, ms);
                    ms.Position = 0;
                    return ms.ToArray();
                }
            }
            ResponseSerializerDelegate responseWriter;
            if (this.ContentTypeResponseSerializers.TryGetValue(contentType, out responseWriter) ||
                this.ContentTypeResponseSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseWriter))
            {
                using (var ms = new MemoryStream())
                {
                    var httpRes = new HttpResponseStreamWrapper(ms);
                    responseWriter(requestContext, response, httpRes);
                    ms.Position = 0;
                    return ms.ToArray();
                }
            }
            var contentTypeAttr = ContentType.GetEndpointAttributes(contentType);
            switch (contentTypeAttr)
            {
                case EndpointAttributes.Xml:
                    return XmlSerializer.SerializeToString(response).ToUtf8Bytes();
                case EndpointAttributes.Json:
                    return JsonDataContractSerializer.Instance.SerializeToString(response).ToUtf8Bytes();
                case EndpointAttributes.Jsv:
                    return TypeSerializer.SerializeToString(response).ToUtf8Bytes();
            }
            throw new NotSupportedException("ContentType not supported: " + contentType);
        }
        public string SerializeToString(IRequestContext requestContext, object response)
        {
            var contentType = requestContext.ResponseContentType;
            StreamSerializerDelegate responseStreamWriter;
            if (this.ContentTypeSerializers.TryGetValue(contentType, out responseStreamWriter) ||
                this.ContentTypeSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseStreamWriter))
            {
                using (var ms = new MemoryStream())
                {
                    responseStreamWriter(requestContext, response, ms);
                    ms.Position = 0;
                    var result = new StreamReader(ms, UTF8EncodingWithoutBom).ReadToEnd();
                    return result;
                }
            }
            ResponseSerializerDelegate responseWriter;
            if (this.ContentTypeResponseSerializers.TryGetValue(contentType, out responseWriter) ||
                this.ContentTypeResponseSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseWriter))
            {
                using (var ms = new MemoryStream())
                {
                    var httpRes = new HttpResponseStreamWrapper(ms);
                    responseWriter(requestContext, response, httpRes);
                    ms.Position = 0;
                    var result = new StreamReader(ms, UTF8EncodingWithoutBom).ReadToEnd();
                    return result;
                }
            }
            var contentTypeAttr = ContentType.GetEndpointAttributes(contentType);
            switch (contentTypeAttr)
            {
                case EndpointAttributes.Xml:
                    return XmlSerializer.SerializeToString(response);
                case EndpointAttributes.Json:
                    return JsonDataContractSerializer.Instance.SerializeToString(response);
                case EndpointAttributes.Jsv:
                    return TypeSerializer.SerializeToString(response);
            }
            throw new NotSupportedException("ContentType not supported: " + contentType);
        }
        public void SerializeToStream(IRequestContext requestContext, object response, Stream responseStream)
        {
            var contentType = requestContext.ResponseContentType;
            var serializer = GetResponseSerializer(contentType);
            if (serializer == null)
                throw new NotSupportedException("ContentType not supported: " + contentType);
            var httpRes = new HttpResponseStreamWrapper(responseStream);
            serializer(requestContext, response, httpRes);
        }
        public void SerializeToResponse(IRequestContext requestContext, object response, IHttpResponse httpResponse)
        {
            var contentType = requestContext.ResponseContentType;


Please complete the code given below. 
using CRMPluginUtils;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace MicrosoftDynamicsCRMPlugin
{
  public class DynamicsSession
  {
    private ConfigurationManager configurationManager = new ConfigurationManager("3CXCRMUser.ini");
    private LoginMgr loginMgr;
    private OrganizationServiceProxy serviceProxy = null;
    private Guid currentUserId = Guid.Empty;
    private bool isActive = false;
    private string createUrl(string id, ContactTypes contactType, string callNumberFlag = null, string newCase = null)
    {
      string currentServiceEndpointUri = serviceProxy.ServiceManagement.CurrentServiceEndpoint.Address.Uri.AbsoluteUri;
      int xrmServicesIndex = currentServiceEndpointUri.IndexOf("/XRMServices", StringComparison.InvariantCultureIgnoreCase);
      string url = xrmServicesIndex < 0 ? currentServiceEndpointUri : currentServiceEndpointUri.Substring(0, xrmServicesIndex);
        switch (contactType)
        {
        case ContactTypes.Account:
            url += String.Format("/main.aspx?etn=account&id={{{0}}}&pagetype=entityrecord", id);
            break;
        case ContactTypes.Contact:
            url += String.Format("/main.aspx?etn=contact&id={{{0}}}&pagetype=entityrecord", id);
            break;
        case ContactTypes.Lead:
            if (callNumberFlag != null)
            {
                url += String.Format("/main.aspx?etn=phonecall&id={{{0}}}&pagetype=entityrecord", id);
                break;
            }
            else if (newCase != null)
            {
                url += String.Format("/main.aspx?etn=incident&id={{{0}}}&pagetype=entityrecord", id);
                break;
            }
            else
            {
                LogHelper.Log(Environment.SpecialFolder.ApplicationData, "MicrosoftDynamicsCRM.log", "Something happened generating the URL, opening lead");
                url += String.Format("/main.aspx?etn=lead&id={{{0}}}&pagetype=entityrecord", id);
                break;
            }
        default:
            break;
        }
      return url;
    }
    private void launchUrl(string url)
    {
      if (configurationManager.GetValue("Microsoft Dynamics Plug-in", "UseDefaultBrowser", "True") == "True")
        Process.Start(url);
      else
      {
        string customBrowserPath = configurationManager.GetValue("Microsoft Dynamics Plug-in", "CustomBrowser", "");
        if (String.IsNullOrEmpty(customBrowserPath))
          throw new ApplicationException(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.CustomBrowserIsEmpty"));
        Process.Start(customBrowserPath, url);
      }
    }
    private void connectivityTest()
    {
      if (serviceProxy == null)
        throw new ApplicationException(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.NotLoggedIn"));
      // Perform a dummy request
      WhoAmIResponse whoResp = (WhoAmIResponse)serviceProxy.Execute(new WhoAmIRequest());
      currentUserId = whoResp.UserId;
    }
    private ContactInfo createNewContactRecord(string contactNumber)
    {
      try
      {
        if (configurationManager.GetValue("Microsoft Dynamics Plug-in", "CreateNewRecordType", "Contact") == "Contact")
        {
          Microsoft.Crm.Sdk.Contact contactItem = new Microsoft.Crm.Sdk.Contact();
          contactItem.Telephone1 = contactNumber;
          contactItem.Description = "Contact created with 3cx plugin";
          Guid newContactId = serviceProxy.Create(contactItem);
          launchUrl(createUrl(newContactId.ToString(), ContactTypes.Contact));
          return new ContactInfo(newContactId.ToString(), contactNumber, ContactTypes.Contact);
        }
        else
        {
          Microsoft.Crm.Sdk.Lead leadItem = new Microsoft.Crm.Sdk.Lead();
          leadItem.Telephone1 = contactNumber;
          Guid newLeadId = serviceProxy.Create(leadItem);
          launchUrl(createUrl(newLeadId.ToString(), ContactTypes.Lead));
          return new ContactInfo(newLeadId.ToString(), contactNumber, ContactTypes.Lead);
        }
      }
      catch (System.ServiceModel.Security.ExpiredSecurityTokenException)
      {
        throw;
      }
      catch (Exception exc)
      {
        throw new ApplicationException(String.Format(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.CreatingContact"), ErrorHelper.GetErrorDescription(exc)));
      }
    }
    public DynamicsSession()
    {
		     var ver = GetVersion();
            if(!string.IsNullOrEmpty(ver))
                LogHelper.Log(Environment.SpecialFolder.ApplicationData, "MicrosoftDynamicsCRM.log", "Plugin Version: " +  ver);
    }
	
	public string GetVersion()
	{
	  try
	  {
			var path = AppDomain.CurrentDomain.BaseDirectory + @"DotNetScripts\MicrosoftDynamicsCRM\VERSION";
			LogHelper.Log(Environment.SpecialFolder.ApplicationData, "MicrosoftDynamicsCRM.log", path);
			return System.IO.File.ReadAllText(path);
		}
	  catch (Exception exc)
	  {
			LogHelper.Log(Environment.SpecialFolder.ApplicationData, "MicrosoftDynamicsCRM.log", "VERSION not found");
	  }
		return string.Empty;
	}
    public bool IsActive
    {
      get { return isActive; }
    }
    public void Login(LoginMgr loginMgr)
    {
      this.loginMgr = loginMgr;
      this.serviceProxy = loginMgr.Login();
      this.serviceProxy.EnableProxyTypes();
      this.isActive = true;
      connectivityTest();
    }
    
    public void Logout()
    {
      if (serviceProxy != null)
      {
        serviceProxy.Dispose();
        serviceProxy = null;
        isActive = false;
      }
    }
    
    public string GetContactNumberByContactId(string phoneType, string contactId)
    {
      if (serviceProxy == null)
        throw new ApplicationException(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.NotLoggedIn"));
      ContactFinder contactFinder = new ContactFinder(serviceProxy);
      ContactInfo contactInfo = contactFinder.GetContactInformationByContactId(phoneType, contactId);
      return contactInfo != null ? contactInfo.Number : null;
    }
    public string GetContactNumberByLeadId(string phoneType, string leadId)
    {
      if (serviceProxy == null)
        throw new ApplicationException(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.NotLoggedIn"));
      ContactFinder contactFinder = new ContactFinder(serviceProxy);
      ContactInfo contactInfo = contactFinder.GetContactInformationByLeadId(phoneType, leadId);
      return contactInfo != null ? contactInfo.Number : null;
    }
    public string GetContactNumberByAccountId(string phoneType, string accountId)
    {
      if (serviceProxy == null)
        throw new ApplicationException(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.NotLoggedIn"));
      ContactFinder contactFinder = new ContactFinder(serviceProxy);
      ContactInfo contactInfo = contactFinder.GetContactInformationByAccountId(phoneType, accountId);
      return contactInfo != null ? contactInfo.Number : null;
    }
    public ContactInfo ShowContactRecord(string contactNumber, bool createIfNotFound)
    {
      if (serviceProxy == null)
        throw new ApplicationException(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.NotLoggedIn"));
      ContactFinder contactFinder = new ContactFinder(serviceProxy);
      ContactInfo contactInfo = contactFinder.GetContactInformation(contactNumber, 4);
      if (contactInfo == null) contactInfo = contactFinder.GetContactInformation(contactNumber, 2);
      bool OpenCaseNotContact = configurationManager.GetValue("Microsoft Dynamics Plug-in", "OpenCaseNotContact", "False") == "True";
        if (OpenCaseNotContact)
        {//creating new case here, need to figure out the crm sdk for create case
         //thinking case needs to be created here
            string CaseNumberGuid = CreateCase(contactInfo).ToString();
            //then launch the record
            launchUrl(createUrl(CaseNumberGuid, ContactTypes.Lead, null, "NotNull")); //passing notnull in third value to trigger case creation in createurl, contactnumber that will be passed in this instance will be the guid for the new case created
            return contactInfo;
        }
        else
        {
            if (contactInfo == null)
            {
                if (createIfNotFound)
                    return createNewContactRecord(contactNumber);
                else
                    throw new ApplicationException(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.ContactNotFound"));
            }
            else
            {
                launchUrl(createUrl(contactInfo.Id, contactInfo.Type));
                return contactInfo;
            }
        }
    }
    public void ShowPhoneCallRecord(Guid CallNumber)
    {
        if (serviceProxy == null)
            throw new ApplicationException(LocalizedResourceManager.GetString("DotNetScript", "DynamicsSession.Error.NotLoggedIn"));
        if (CallNumber == null)
        {
                LogHelper.Log(Environment.SpecialFolder.ApplicationData, "MicrosoftDynamicsCRM.log", "Call not found");
        }
        else
        {


Please complete the code given below. 
package org.intermine.sql.query;
/*
 * Copyright (C) 2002-2014 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
 * Subclass of ExplainResult specific to PostgreSQL.
 *
 * @author Matthew Wakeling
 * @author Andrew Varley
 * @version 1.0
 */
public class PostgresExplainResult extends ExplainResult
{
    /*
     * Fields inherited from ExplainResult:
     * protected long rows, start, complete, width, estimatedRows
     */
    private String explainText = null;
    /**
     * Constructs an instance of PostgresExplainResult without any data.
     *
     */
    protected PostgresExplainResult() {
    }
    /**
     * Constructs an instance of PostgresExplainResult for a given Query and
     * database Connection.
     *
     * @param query the org.intermine.sql.query.Query to be explained
     * @param database a java.sql.Connection by which to access the database
     * @throws SQLException if a database error occurs
     * @throws NullPointerException if either query or database are null
     */
    public PostgresExplainResult(Query query, Connection database) throws SQLException {
        this(query.getSQLString(), database);
    }
    /**
     * Constructs an instance of PostgresExplainResult for a given Query String and database
     * Connection.
     *
     * @param query the String query to be explained
     * @param database a java.sql.Connection by which to access the database
     * @throws SQLException if a database error occurs
     * @throws NullPointerException if either query or database are null
     */
    public PostgresExplainResult(String query, Connection database) throws SQLException {
        if ((query == null) || (database == null)) {
            throw new NullPointerException("Arguments cannot be null");
        }
        Statement s = database.createStatement();
        if (!query.toUpperCase().startsWith("EXPLAIN ")) {
            query = "explain " + query;
        }
        try {
            s.execute(query);
            retrieveExplainString(s);
            s.close();
        } catch (SQLException e) {
            SQLException e2 = new SQLException("Error running query \"" + query + "\"");
            e2.initCause(e);
            throw e2;
        }
    }
    /**
     * Constructs an instance of ExplainResult given a PreparedStatement
     * object.  Assumes that sql string already has EXPLAIN at beginning
     *
     * @param stmt the PreparedStatement to be explained
     * @throws SQLException if the query cannot be explained by that database
     */
    public PostgresExplainResult(PreparedStatement stmt) throws SQLException {
        if (stmt == null) {
            throw (new NullPointerException("PreparedStatement argument cannot be null"));
        }
        Connection database = stmt.getConnection();
        if (database == null) {
            throw (new NullPointerException("Failed to retrieve Connection"
                                            + " from PreparedStatement"));
        }
        stmt.execute();
        retrieveExplainString(stmt);
        stmt.close();
    }
    /**
     * Returns the text of the explain result, in human readable form.
     *
     * @return a String
     */
    public String getExplainText() {
        return explainText;
    }
    /**
     * Retrieve EXPLAIN String from post-7.3 databases
     *
     * @param stmt the Statement that ran the EXPLAIN
     * @throws SQLException if a database error occurs
     */
    protected void retrieveExplainString(Statement stmt) throws SQLException {
        ResultSet results = stmt.getResultSet();
        if ((results == null) || !results.next()) {
            throw (new SQLException("Failed to get a valid explain string from database"));
        }
        String text = results.getString(1);
        try {
            parseWarningString(text);
        } catch (RuntimeException e) {
            throw (new SQLException("Error parsing EXPLAIN string: " + e));
        }
        StringBuffer explainTextBuffer = new StringBuffer(text).append("\n");
        while (results.next()) {
            explainTextBuffer.append(results.getString(1)).append("\n");
        }
        explainText = explainTextBuffer.toString();
        if (stmt.getMoreResults()) {
            throw new SQLException("Database returned more than ResultSet while EXPLAINing");
        }
    }
    /**
     * Parses the warning returned by the database into statistics for the
     * ExplainResult object.
     *
     * @param text the String returned by the database
     * @throws IllegalArgumentException if text is not a valid EXPLAIN result
     * @throws NullPointerException if text is null
     */
    void parseWarningString(String text) {
        int nextToken = text.indexOf("(cost=") + 6;
        if (nextToken < 6) {
            throw (new IllegalArgumentException("Invalid EXPLAIN string: no \"(cost=\" bad string: "
                    + text));
        }
        int endOfString = text.indexOf(')', nextToken);
        if (endOfString < 0) {
            throw (new IllegalArgumentException("Invalid EXPLAIN string: no \")\" bad string "
                    + text));
        }
        text = text.substring(nextToken, endOfString);
        nextToken = text.indexOf("..");
        if (nextToken < 0) {
            throw (new IllegalArgumentException("Invalid EXPLAIN string: no \"..\" bad string: "
                    + text));
        }
        String toParse = text.substring(0, text.indexOf('.'))
            + text.substring(text.indexOf('.') + 1, text.indexOf('.') + 2);
        try {
            start = Long.parseLong(toParse);
        } catch (NumberFormatException e) {
            start = Long.MAX_VALUE;
        }
        text = text.substring(nextToken + 2);
        nextToken = text.indexOf(" rows=");
        if (nextToken < 0) {
            throw (new IllegalArgumentException("Invalid EXPLAIN string: no \" rows=\""));
        }
        toParse = text.substring(0, text.indexOf('.'))
            + text.substring(text.indexOf('.') + 1, text.indexOf('.') + 2);
        try {
            complete = Long.parseLong(toParse);
        } catch (NumberFormatException e) {
            complete = Long.MAX_VALUE;
        }
        text = text.substring(nextToken + 6);
        nextToken = text.indexOf(" width=");
        if (nextToken < 0) {
            throw (new IllegalArgumentException("Invalid EXPLAIN string: no \" width=\" bad string:"
                    + text));
        }
        try {
            rows = Long.parseLong(text.substring(0, nextToken));
        } catch (NumberFormatException e) {
            rows = Long.MAX_VALUE;
        }
        estimatedRows = rows;


Please complete the code given below. 
package org.netlib.lapack;
import org.netlib.blas.Dcopy;
import org.netlib.err.Xerbla;
import org.netlib.util.doubleW;
import org.netlib.util.intW;
public final class Dlasda
{
  public static void dlasda(int paramInt1, int paramInt2, int paramInt3, int paramInt4, double[] paramArrayOfDouble1, int paramInt5, double[] paramArrayOfDouble2, int paramInt6, double[] paramArrayOfDouble3, int paramInt7, int paramInt8, double[] paramArrayOfDouble4, int paramInt9, int[] paramArrayOfInt1, int paramInt10, double[] paramArrayOfDouble5, int paramInt11, double[] paramArrayOfDouble6, int paramInt12, double[] paramArrayOfDouble7, int paramInt13, double[] paramArrayOfDouble8, int paramInt14, int[] paramArrayOfInt2, int paramInt15, int[] paramArrayOfInt3, int paramInt16, int paramInt17, int[] paramArrayOfInt4, int paramInt18, double[] paramArrayOfDouble9, int paramInt19, double[] paramArrayOfDouble10, int paramInt20, double[] paramArrayOfDouble11, int paramInt21, double[] paramArrayOfDouble12, int paramInt22, int[] paramArrayOfInt5, int paramInt23, intW paramintW)
  {
    int i = 0;
    int j = 0;
    int k = 0;
    int m = 0;
    int n = 0;
    int i1 = 0;
    int i2 = 0;
    int i3 = 0;
    int i4 = 0;
    int i5 = 0;
    int i6 = 0;
    int i7 = 0;
    int i8 = 0;
    int i9 = 0;
    int i10 = 0;
    int i11 = 0;
    intW localintW1 = new intW(0);
    int i12 = 0;
    int i13 = 0;
    int i14 = 0;
    int i15 = 0;
    int i16 = 0;
    int i17 = 0;
    intW localintW2 = new intW(0);
    int i18 = 0;
    int i19 = 0;
    int i20 = 0;
    int i21 = 0;
    int i22 = 0;
    int i23 = 0;
    int i24 = 0;
    int i25 = 0;
    int i26 = 0;
    int i27 = 0;
    int i28 = 0;
    int i29 = 0;
    doubleW localdoubleW1 = new doubleW(0.0D);
    doubleW localdoubleW2 = new doubleW(0.0D);
    paramintW.val = 0;
    if ((paramInt1 >= 0 ? 0 : 1) == 0) {}
    if (((paramInt1 <= 1 ? 0 : 1) == 0 ? 0 : 1) != 0)
    {
      paramintW.val = -1;
    }
    else if ((paramInt2 >= 3 ? 0 : 1) != 0)
    {
      paramintW.val = -2;
    }
    else if ((paramInt3 >= 0 ? 0 : 1) != 0)
    {
      paramintW.val = -3;
    }
    else
    {
      if ((paramInt4 >= 0 ? 0 : 1) == 0) {}
      if (((paramInt4 <= 1 ? 0 : 1) == 0 ? 0 : 1) != 0) {
        paramintW.val = -4;
      } else if ((paramInt8 >= paramInt3 + paramInt4 ? 0 : 1) != 0) {
        paramintW.val = -8;
      } else if ((paramInt17 >= paramInt3 ? 0 : 1) != 0) {
        paramintW.val = -17;
      }
    }
    if ((paramintW.val == 0 ? 0 : 1) != 0)
    {
      Xerbla.xerbla("DLASDA", -paramintW.val);
      return;
    }
    i10 = paramInt3 + paramInt4;
    if ((paramInt3 > paramInt2 ? 0 : 1) != 0)
    {
      if ((paramInt1 != 0 ? 0 : 1) != 0) {
        Dlasdq.dlasdq("U", paramInt4, paramInt3, 0, 0, 0, paramArrayOfDouble1, paramInt5, paramArrayOfDouble2, paramInt6, paramArrayOfDouble4, paramInt9, paramInt8, paramArrayOfDouble3, paramInt7, paramInt8, paramArrayOfDouble3, paramInt7, paramInt8, paramArrayOfDouble12, paramInt22, paramintW);
      } else {
        Dlasdq.dlasdq("U", paramInt4, paramInt3, i10, paramInt3, 0, paramArrayOfDouble1, paramInt5, paramArrayOfDouble2, paramInt6, paramArrayOfDouble4, paramInt9, paramInt8, paramArrayOfDouble3, paramInt7, paramInt8, paramArrayOfDouble3, paramInt7, paramInt8, paramArrayOfDouble12, paramInt22, paramintW);
      }
      return;
    }
    i2 = 1;
    i13 = i2 + paramInt3;
    i14 = i13 + paramInt3;
    m = i14 + paramInt3;
    i4 = m + paramInt3;
    i11 = 0;
    i21 = 0;
    i24 = paramInt2 + 1;
    i26 = 1;
    i28 = i26 + i10;
    i22 = i28 + i10;
    i23 = i22 + i24 * i24;
    Dlasdt.dlasdt(paramInt3, localintW2, localintW1, paramArrayOfInt5, i2 - 1 + paramInt23, paramArrayOfInt5, i13 - 1 + paramInt23, paramArrayOfInt5, i14 - 1 + paramInt23, paramInt2);
    i12 = (localintW1.val + 1) / 2;
    i = i12;
    int i31;
    for (int i30 = localintW1.val - i12 + 1; i30 > 0; i30--)
    {
      j = i - 1;
      k = paramArrayOfInt5[(i2 + j - 1 + paramInt23)];
      i15 = paramArrayOfInt5[(i13 + j - 1 + paramInt23)];
      i17 = i15 + 1;
      i18 = paramArrayOfInt5[(i14 + j - 1 + paramInt23)];
      i16 = k - i15;
      i19 = k + 1;
      n = m + i16 - 2;
      i27 = i26 + i16 - 1;
      i29 = i28 + i16 - 1;
      i25 = 1;
      if ((paramInt1 != 0 ? 0 : 1) != 0)
      {
        Dlaset.dlaset("A", i17, i17, 0.0D, 1.0D, paramArrayOfDouble12, i22 - 1 + paramInt22, i24);
        Dlasdq.dlasdq("U", i25, i15, i17, i21, i11, paramArrayOfDouble1, i16 - 1 + paramInt5, paramArrayOfDouble2, i16 - 1 + paramInt6, paramArrayOfDouble12, i22 - 1 + paramInt22, i24, paramArrayOfDouble12, i23 - 1 + paramInt22, i15, paramArrayOfDouble12, i23 - 1 + paramInt22, i15, paramArrayOfDouble12, i23 - 1 + paramInt22, paramintW);
        i3 = i22 + i15 * i24;
        Dcopy.dcopy(i17, paramArrayOfDouble12, i22 - 1 + paramInt22, 1, paramArrayOfDouble12, i27 - 1 + paramInt22, 1);
        Dcopy.dcopy(i17, paramArrayOfDouble12, i3 - 1 + paramInt22, 1, paramArrayOfDouble12, i29 - 1 + paramInt22, 1);
      }
      else
      {
        Dlaset.dlaset("A", i15, i15, 0.0D, 1.0D, paramArrayOfDouble3, i16 - 1 + (1 - 1) * paramInt8 + paramInt7, paramInt8);
        Dlaset.dlaset("A", i17, i17, 0.0D, 1.0D, paramArrayOfDouble4, i16 - 1 + (1 - 1) * paramInt8 + paramInt9, paramInt8);
        Dlasdq.dlasdq("U", i25, i15, i17, i15, i11, paramArrayOfDouble1, i16 - 1 + paramInt5, paramArrayOfDouble2, i16 - 1 + paramInt6, paramArrayOfDouble4, i16 - 1 + (1 - 1) * paramInt8 + paramInt9, paramInt8, paramArrayOfDouble3, i16 - 1 + (1 - 1) * paramInt8 + paramInt7, paramInt8, paramArrayOfDouble3, i16 - 1 + (1 - 1) * paramInt8 + paramInt7, paramInt8, paramArrayOfDouble12, i22 - 1 + paramInt22, paramintW);
        Dcopy.dcopy(i17, paramArrayOfDouble4, i16 - 1 + (1 - 1) * paramInt8 + paramInt9, 1, paramArrayOfDouble12, i27 - 1 + paramInt22, 1);
        Dcopy.dcopy(i17, paramArrayOfDouble4, i16 - 1 + (i17 - 1) * paramInt8 + paramInt9, 1, paramArrayOfDouble12, i29 - 1 + paramInt22, 1);
      }
      if ((paramintW.val == 0 ? 0 : 1) != 0) {
        return;
      }
      i5 = 1;
      for (i31 = i15 - 1 + 1; i31 > 0; i31--)
      {
        paramArrayOfInt5[(n + i5 - 1 + paramInt23)] = i5;
        i5 += 1;
      }
      if ((i != localintW1.val ? 0 : 1) != 0) {}
      if (((paramInt4 != 0 ? 0 : 1) != 0 ? 1 : 0) != 0) {
        i25 = 0;
      } else {
        i25 = 1;
      }
      n += i17;
      i27 += i17;
      i29 += i17;
      i20 = i18 + i25;
      if ((paramInt1 != 0 ? 0 : 1) != 0)
      {
        Dlaset.dlaset("A", i20, i20, 0.0D, 1.0D, paramArrayOfDouble12, i22 - 1 + paramInt22, i24);
        Dlasdq.dlasdq("U", i25, i18, i20, i21, i11, paramArrayOfDouble1, i19 - 1 + paramInt5, paramArrayOfDouble2, i19 - 1 + paramInt6, paramArrayOfDouble12, i22 - 1 + paramInt22, i24, paramArrayOfDouble12, i23 - 1 + paramInt22, i18, paramArrayOfDouble12, i23 - 1 + paramInt22, i18, paramArrayOfDouble12, i23 - 1 + paramInt22, paramintW);
        i3 = i22 + (i20 - 1) * i24;
        Dcopy.dcopy(i20, paramArrayOfDouble12, i22 - 1 + paramInt22, 1, paramArrayOfDouble12, i27 - 1 + paramInt22, 1);
        Dcopy.dcopy(i20, paramArrayOfDouble12, i3 - 1 + paramInt22, 1, paramArrayOfDouble12, i29 - 1 + paramInt22, 1);
      }
      else
      {
        Dlaset.dlaset("A", i18, i18, 0.0D, 1.0D, paramArrayOfDouble3, i19 - 1 + (1 - 1) * paramInt8 + paramInt7, paramInt8);
        Dlaset.dlaset("A", i20, i20, 0.0D, 1.0D, paramArrayOfDouble4, i19 - 1 + (1 - 1) * paramInt8 + paramInt9, paramInt8);
        Dlasdq.dlasdq("U", i25, i18, i20, i18, i11, paramArrayOfDouble1, i19 - 1 + paramInt5, paramArrayOfDouble2, i19 - 1 + paramInt6, paramArrayOfDouble4, i19 - 1 + (1 - 1) * paramInt8 + paramInt9, paramInt8, paramArrayOfDouble3, i19 - 1 + (1 - 1) * paramInt8 + paramInt7, paramInt8, paramArrayOfDouble3, i19 - 1 + (1 - 1) * paramInt8 + paramInt7, paramInt8, paramArrayOfDouble12, i22 - 1 + paramInt22, paramintW);
        Dcopy.dcopy(i20, paramArrayOfDouble4, i19 - 1 + (1 - 1) * paramInt8 + paramInt9, 1, paramArrayOfDouble12, i27 - 1 + paramInt22, 1);
        Dcopy.dcopy(i20, paramArrayOfDouble4, i19 - 1 + (i20 - 1) * paramInt8 + paramInt9, 1, paramArrayOfDouble12, i29 - 1 + paramInt22, 1);
      }
      if ((paramintW.val == 0 ? 0 : 1) != 0) {
        return;
      }
      i5 = 1;
      for (i31 = i18 - 1 + 1; i31 > 0; i31--)
      {
        paramArrayOfInt5[(n + i5 - 1 + paramInt23)] = i5;
        i5 += 1;
      }
      i += 1;
    }
    i5 = (int)Math.pow(2, localintW2.val);
    i8 = localintW2.val;
    for (int i30 = (1 - localintW2.val + -1) / -1; i30 > 0; i30--)
    {
      i9 = i8 * 2 - 1;
      if ((i8 != 1 ? 0 : 1) != 0)
      {
        i6 = 1;
        i7 = 1;
      }
      else
      {
        i6 = (int)Math.pow(2, i8 - 1);
        i7 = 2 * i6 - 1;
      }
      i = i6;
      for (i31 = i7 - i6 + 1; i31 > 0; i31--)
      {
        i1 = i - 1;
        k = paramArrayOfInt5[(i2 + i1 - 1 + paramInt23)];
        i15 = paramArrayOfInt5[(i13 + i1 - 1 + paramInt23)];
        i18 = paramArrayOfInt5[(i14 + i1 - 1 + paramInt23)];
        i16 = k - i15;
        i19 = k + 1;


Please complete the code given below. 
/*
 * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.security.util;
import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
 * Algorithm constraints for disabled algorithms property
 *
 * See the "jdk.certpath.disabledAlgorithms" specification in java.security
 * for the syntax of the disabled algorithm string.
 */
public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
    private static final Debug debug = Debug.getInstance("certpath");
    // the known security property, jdk.certpath.disabledAlgorithms
    public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
            "jdk.certpath.disabledAlgorithms";
    // the known security property, jdk.tls.disabledAlgorithms
    public static final String PROPERTY_TLS_DISABLED_ALGS =
            "jdk.tls.disabledAlgorithms";
    private final String[] disabledAlgorithms;
    private final Constraints algorithmConstraints;
    /**
     * Initialize algorithm constraints with the specified security property.
     *
     * @param propertyName the security property name that define the disabled
     *        algorithm constraints
     */
    public DisabledAlgorithmConstraints(String propertyName) {
        this(propertyName, new AlgorithmDecomposer());
    }
    public DisabledAlgorithmConstraints(String propertyName,
            AlgorithmDecomposer decomposer) {
        super(decomposer);
        disabledAlgorithms = getAlgorithms(propertyName);
        algorithmConstraints = new Constraints(disabledAlgorithms);
    }
    /*
     * This only checks if the algorithm has been completely disabled.  If
     * there are keysize or other limit, this method allow the algorithm.
     */
    @Override
    public final boolean permits(Set<CryptoPrimitive> primitives,
            String algorithm, AlgorithmParameters parameters) {
        if (primitives == null || primitives.isEmpty()) {
            throw new IllegalArgumentException(
                        "No cryptographic primitive specified");
        }
        return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
    }
    /*
     * Checks if the key algorithm has been disabled or constraints have been
     * placed on the key.
     */
    @Override
    public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {
        return checkConstraints(primitives, "", key, null);
    }
    /*
     * Checks if the key algorithm has been disabled or if constraints have
     * been placed on the key.
     */
    @Override
    public final boolean permits(Set<CryptoPrimitive> primitives,
            String algorithm, Key key, AlgorithmParameters parameters) {
        if (algorithm == null || algorithm.length() == 0) {
            throw new IllegalArgumentException("No algorithm name specified");
        }
        return checkConstraints(primitives, algorithm, key, parameters);
    }
    /*
     * Check if a x509Certificate object is permitted.  Check if all
     * algorithms are allowed, certificate constraints, and the
     * public key against key constraints.
     *
     * Uses new style permit() which throws exceptions.
     */
    public final void permits(Set<CryptoPrimitive> primitives,
            CertConstraintParameters cp) throws CertPathValidatorException {
        checkConstraints(primitives, cp);
    }
    /*
     * Check if Certificate object is within the constraints.
     * Uses new style permit() which throws exceptions.
     */
    public final void permits(Set<CryptoPrimitive> primitives,
            X509Certificate cert) throws CertPathValidatorException {
        checkConstraints(primitives, new CertConstraintParameters(cert));
    }
    // Check if a string is contained inside the property
    public boolean checkProperty(String param) {
        param = param.toLowerCase(Locale.ENGLISH);
        for (String block : disabledAlgorithms) {
            if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
                return true;
            }
        }
        return false;
    }
    // Check algorithm constraints with key and algorithm
    private boolean checkConstraints(Set<CryptoPrimitive> primitives,
            String algorithm, Key key, AlgorithmParameters parameters) {
        // check the key parameter, it cannot be null.
        if (key == null) {
            throw new IllegalArgumentException("The key cannot be null");
        }
        // check the signature algorithm
        if (algorithm != null && algorithm.length() != 0) {
            if (!permits(primitives, algorithm, parameters)) {
                return false;
            }
        }
        // check the key algorithm
        if (!permits(primitives, key.getAlgorithm(), null)) {
            return false;
        }
        // check the key constraints
        return algorithmConstraints.permits(key);
    }
    /*
     * Check algorithm constraints with Certificate
     * Uses new style permit() which throws exceptions.
     */
    private void checkConstraints(Set<CryptoPrimitive> primitives,
            CertConstraintParameters cp) throws CertPathValidatorException {
        X509Certificate cert = cp.getCertificate();
        String algorithm = cert.getSigAlgName();
        // Check signature algorithm is not disabled
        if (!permits(primitives, algorithm, null)) {
            throw new CertPathValidatorException(
                    "Algorithm constraints check failed on disabled "+
                            "signature algorithm: " + algorithm,
                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
        }
        // Check key algorithm is not disabled
        if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
            throw new CertPathValidatorException(
                    "Algorithm constraints check failed on disabled "+
                            "public key algorithm: " + algorithm,
                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
        }
        // Check the certificate and key constraints
        algorithmConstraints.permits(cp);
    }
    /**
     * Key and Certificate Constraints
     *
     * The complete disabling of an algorithm is not handled by Constraints or
     * Constraint classes.  That is addressed with
     *   permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
     *
     * When passing a Key to permit(), the boolean return values follow the
     * same as the interface class AlgorithmConstraints.permit().  This is to
     * maintain compatibility:
     * 'true' means the operation is allowed.
     * 'false' means it failed the constraints and is disallowed.
     *
     * When passing CertConstraintParameters through permit(), an exception
     * will be thrown on a failure to better identify why the operation was
     * disallowed.
     */
    private static class Constraints {
        private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
        private static final Pattern keySizePattern = Pattern.compile(
                "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
        private static final Pattern denyAfterPattern = Pattern.compile(
                "denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");
        public Constraints(String[] constraintArray) {
            for (String constraintEntry : constraintArray) {
                if (constraintEntry == null || constraintEntry.isEmpty()) {
                    continue;
                }
                constraintEntry = constraintEntry.trim();


Please complete the code given below. 
/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2007 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/
package org.vrjuggler.vrjconfig.commoneditors.devicegraph;
import java.awt.Dimension;
import java.awt.geom.Rectangle2D;
import java.util.*;
import org.jgraph.JGraph;
import org.jgraph.graph.AttributeMap;
import org.jgraph.graph.CellView;
import org.jgraph.graph.ConnectionSet;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultPort;
import org.jgraph.graph.GraphCell;
import org.jgraph.graph.GraphConstants;
import org.vrjuggler.jccl.config.*;
import org.vrjuggler.vrjconfig.commoneditors.DeviceGraph;
import org.vrjuggler.vrjconfig.commoneditors.EditorConstants;
/**
 * A collection of helper functions that can be helpful in extending JGraph.
 *
 * <p>
 * The basic structure of a device graph is relatively straightfoward.  There
 * are three types of cells: edges, proxy vertices, and device vertices.
 * Edges must always be of type <code>ProxyToDeviceEdge</code>.  Proxy vertices
 * have the following characteristics:
 *
 * <ul>
 *   <li>
 *     Is of type <code>org.jgraph.graph.DefaultGraphCell</code>
 *   </li>
 *   <li>
 *     Contains a user object of type <code>ProxyInfo</code>
 *   </li>
 *   <li>
 *     Has a single port (type <code>DefaultPort</code>) with at most one
 *     out-going edge
 *   </li>
 * </ul>
 *
 * Device vertices, on the other hand, have these characteristics:
 *
 * <ul>
 *   <li>
 *     Is of type <code>org.jgraph.graph.DefaultGraphCell</code>
 *   </li>
 *   <li>
 *     Contains a user object of type <code>DeviceInfo</code>
 *   </li>
 *   <li>
 *     Has one or more ports (type <code>DefaultPort</code>), each of which
 *     contains a user object of type <code>UnitInfo</code>
 *   </li>
 * </ul>
 *
 * <p>
 * The functions included in this class take care of all the details related
 * to creating and connecting cells.  In particular, there are functions that
 * know about all the default device and device proxy config element types in
 * VR Juggler and know how to create cells and proxies for those types.
 * </p>
 *
 * @see DeviceInfo
 * @see ProxyInfo
 * @see UnitInfo
 * @see ProxyToDeviceEdge
 * @see org.jgraph.graph.DefaultGraphCell
 * @see org.jgraph.graph.DefaultPort
 */
public abstract class GraphHelpers
   implements EditorConstants
{
   private static Map mDevCellCreatorMap = new HashMap();
   /**
    * Registers the given device graph cell creator as the creator for the
    * given config definition.  Subsequent calls to 
    * <code>createDeviceCell(ConfigElement,ConfigContext,Map)</code> will be
    * able to create device graph cells for the given config definition.
    *
    * @param def        the config definition that uniquely identifies which
    *                   creator to be used
    * @param c          the device graph cell creator
    *
    * @see #createDeviceCell(ConfigElement,ConfigContext,Map)
    */
   public static void registerGraphCellCreator(ConfigDefinition def,
                                               DeviceGraphCellCreator c)
   {
      mDevCellCreatorMap.put(def, c);
   }
   /**
    * Changes the size of the given <code>CellView</code> reference to be the
    * given dimensions.  The graph cell associated with the given view must be
    * in the given graph.  If the cell view is resized successfully, an edit is
    * posted with the graph's layout cache, and the graph is repainted.
    *
    * @param graph      the graph that knows about the cell view and its cell
    * @param size       the new dimensions for the cell view
    * @param view       the cell view to be resized
    *
    * @see #autoSizeCellView(Dimension,CellView,Hashtable)
    */
   public static void autoSizeCellView(JGraph graph, Dimension size,
                                       CellView view)
   {
      Hashtable table = new Hashtable();
      if ( autoSizeCellView(size, view, table) )
      {
         graph.getGraphLayoutCache().edit(table, null, null, null);
         graph.repaint();
      }
   }
   /**
    * Changes the size of the given <code>CellView</code> reference to be the
    * given dimensions.  The resizing is done by modifying the bounds in the
    * cell view's attributes.  The position of the cell view is left unchanged,
    * but the width and height are changed to the values given in
    * <code>size</code>.  The new attributes are placed into the given
    * <code>Hashtable</code> object using the view's cell as the key.
    *
    * @param size       the new dimensions for the cell view
    * @param view       the cell view to be resized
    * @param table      a non-null hashtable used for storing the modified cell
    *                   view attributes
    *
    * @see org.jgraph.graph.GraphConstants#setBounds(Map,Rectangle2D)
    * @see org.jgraph.graph.CellView#getCell()
    */
   public static boolean autoSizeCellView(Dimension size, CellView view,
                                          Hashtable table)
   {
      boolean edited = false;
      Rectangle2D bounds = GraphConstants.getBounds(view.getAllAttributes());
      if ( bounds != null )
      {
         bounds = (Rectangle2D) bounds.clone();
         bounds.setFrame(bounds.getX(), bounds.getY(), size.width, size.height);
         AttributeMap map = new AttributeMap();
         GraphConstants.setBounds(map, bounds);
         table.put(view.getCell(), map);
         edited = true;
      }
      return edited;
   }
   /**
    * Creates a new graph cell for the given config element that is used to
    * configure an input device.  Pluggable "creators" are used to construct
    * the appropriate <code>DefaultGraphCell</code> instance (with its ports)
    * that is returned.  The creator to use is determined using the config
    * definition of the given config element.  This method is intended to be
    * used for ensuring correct and easy graph cell creation for config
    * elements used to configure devices.  Creators must be registered prior
    * to calling this function.
    *
    * @param devElt     the config element for the device being represented by
    *                   the vertex cell to be created
    * @param context    the config context where <code>devElt</code> exists
    * @param attributes the attribute map where the vertex cell's default
    *                   attribute map will be stored by this function
    *
    * @throws IllegalArgumentException
    *   thrown when the graph cell cannot be created due to one of two
    *   causes: there is no creator known for the config definition of
    *   <code>devElt</code> or the registered creator failed
    *
    * @see #registerGraphCellCreator(ConfigDefinition,DeviceGraphCellCreator)
    */
   public static DefaultGraphCell createDeviceCell(ConfigElement devElt,
                                                   ConfigContext context,
                                                   Map attributes)
   {
      DefaultGraphCell cell = null;
      ConfigDefinition def = devElt.getDefinition();
      DeviceGraphCellCreator creator =
         (DeviceGraphCellCreator) mDevCellCreatorMap.get(def);
      if ( creator != null )
      {
         cell = creator.createDeviceGraphCell(devElt, context, attributes);
      }
      // If creator is null, cell will be null.  If the creator failed, cell
      // will be null.
      if ( cell == null )
      {
         throw new IllegalArgumentException("Unexpected definition " +
                                            def.getToken());
      }
      return cell;
   }
   /**
    * Creates a new graph cell for the given config element that is used to
    * configure an input device, which has exactly one input source (unit)
    * at all times.  The number of units indicates how many ports the new
    * graph cell should have initially.
    *
    * @param devElt             the config element for the device being
    *                           represented by the vertex cell to be created
    * @param context            the config context where <code>devElt</code>
    *                           exists
    * @param attributes         the attribute map where the vertex cell's
    *                           default attribute map will be stored by this
    *                           function
    * @param x                  the X coordinate for the initial positionaing
    *                           of the new vertex
    * @param y                  the Y coordinate for the initial positionaing
    *                           of the new vertex
    * @param autoSize           flag indicating whether the new cell should be
    *                           auto-sized
    *
    * @see #createDeviceCell(ConfigElement,ConfigContext,int,Map,int,int,boolean)
    * @see #createBaseDeviceCell(BaseDeviceInfo,Map,int,int,boolean)
    */
   public static DefaultGraphCell createDeviceCell(ConfigElement devElt,
                                                   ConfigContext context,
                                                   Map attributes, int x,
                                                   int y, boolean autoSize)
   {
      return createDeviceCell(devElt, context, 1, attributes, x, y, autoSize);
   }
   /**
    * Creates a new graph cell for the given config element that is used to
    * configure an input device.  The number of units is determined based on
    * the value of <code>unitPropName</code>.  If it is non-null, then
    * <code>devElt</code> is queried for the number of values of the named
    * property.  Further, a non-null value for <code>unitPropName</code>
    * indicates that the number of values is variable.  If
    * <code>unitPropName</code> is null, then the number of units is set to 1
    * and is treated as non-variable.  The number of units indicates how many
    * ports the new graph cell should have initially.
    *
    * @param devElt             the config element for the device being
    *                           represented by the vertex cell to be created
    * @param context            the config context where <code>devElt</code>
    *                           exists
    * @param unitPropName       the name of the property that indicates the
    *                           number of available units for the represented
    *                           device
    * @param attributes         the attribute map where the vertex cell's
    *                           default attribute map will be stored by this
    *                           function
    * @param x                  the X coordinate for the initial positionaing
    *                           of the new vertex
    * @param y                  the Y coordinate for the initial positionaing
    *                           of the new vertex
    * @param autoSize           flag indicating whether the new cell should be
    *                           auto-sized
    *
    * @see #createBaseDeviceCell(BaseDeviceInfo,Map,int,int,boolean)
    */
   public static DefaultGraphCell createDeviceCell(ConfigElement devElt,
                                                   ConfigContext context,
                                                   String unitPropName,
                                                   Map attributes, int x,
                                                   int y, boolean autoSize)
   {
      DefaultGraphCell dev_cell =
         createBaseDeviceCell(new DeviceInfo(devElt, context, unitPropName),
                              attributes, x, y, autoSize);
      // If unitPropName is null, that means that the number of units for the
      // device being represented by dev_cell is exactly 1 at all times.
      // Otherwise, we get the current number of units by querying devElt.
      int num_units =
         (unitPropName == null) ? 1
                                : devElt.getPropertyValueCount(unitPropName);
      addDevicePorts(dev_cell,
                     UnitTypeHelpers.getSingleUnitType(devElt.getDefinition()),
                     num_units);
      return dev_cell;
   }
   /**
    * Creates a new graph cell for the given config element that is used to
    * configure an input device.  The number of units (specified by the
    * <code>numUnits</code> parameter) indicates the fixed number of ports
    * the new graph cell has.
    *
    * @param devElt             the config element for the device being
    *                           represented by the vertex cell to be created
    * @param context            the config context where <code>devElt</code>
    *                           exists
    * @param numUnits           the fixed number of units this device has
    * @param attributes         the attribute map where the vertex cell's
    *                           default attribute map will be stored by this
    *                           function
    * @param x                  the X coordinate for the initial positionaing
    *                           of the new vertex
    * @param y                  the Y coordinate for the initial positionaing
    *                           of the new vertex
    * @param autoSize           flag indicating whether the new cell should be
    *                           auto-sized
    *
    * @see #createBaseDeviceCell(BaseDeviceInfo,Map,int,int,boolean)
    */
   public static DefaultGraphCell createDeviceCell(ConfigElement devElt,
                                                   ConfigContext context,
                                                   int numUnits,
                                                   Map attributes, int x,
                                                   int y, boolean autoSize)
   {
      // Create a DeviceInfo object with a fixed number of units.
      DefaultGraphCell dev_cell =
         createBaseDeviceCell(new DeviceInfo(devElt, context), attributes,
                              x, y, autoSize);
      addDevicePorts(dev_cell,
                     UnitTypeHelpers.getSingleUnitType(devElt.getDefinition()),
                     numUnits);
      return dev_cell;
   }
   /**
    * Creates a new graph cell for the given config element that is used to
    * configure an input device using "artificial" input sources (units).
    *
    * @param devElt     the config element for the device being
    *                   represented by the vertex cell to be created
    * @param context    the config context where <code>devElt</code> exists
    * @param proxyTypes the list of proxy types that can point at the device
    * @param attributes the attribute map where the vertex cell's default
    *                   attribute map will be stored by this function
    * @param x          the X coordinate for the initial positionaing of the
    *                   new vertex
    * @param y          the Y coordinate for the initial positionaing of the
    *                   new vertex
    * @param autoSize   flag indicating whether the new cell should be
    *                   auto-sized
    *
    * @see #createBaseDeviceCell(BaseDeviceInfo,Map,int,int,boolean)
    */
   public static DefaultGraphCell createDeviceCell(ConfigElement devElt,
                                                   ConfigContext context,
                                                   List proxyTypes,
                                                   Map attributes,
                                                   int x, int y,
                                                   boolean autoSize)
   {
      ConfigBroker broker = new ConfigBrokerProxy();
      List all_elts = broker.getElements(context);
      Map unit_map = new HashMap();
      for ( Iterator d = proxyTypes.iterator(); d.hasNext(); )
      {
         Object def_obj = d.next();
         List all_proxy_elts = null;
         if ( def_obj instanceof String )
         {
            all_proxy_elts = 
               ConfigUtilities.getElementsWithDefinition(all_elts,
                                                         (String) def_obj);
         }
         else if ( def_obj instanceof ConfigDefinition )
         {
            all_proxy_elts = 
               ConfigUtilities.getElementsWithDefinition(all_elts,
                                                         (ConfigDefinition) def_obj);
         }
         if ( ! all_proxy_elts.isEmpty() )
         {
            ConfigDefinition def = 
               ((ConfigElement) all_proxy_elts.get(0)).getDefinition();
            PropertyDefinition prop_def =
               def.getPropertyDefinition(DEVICE_PROPERTY);
            Integer unit_type =
               UnitTypeHelpers.getUnitType(prop_def.getAllowedType(0));
            int proxy_count = 0;
            for ( Iterator e = all_proxy_elts.iterator(); e.hasNext(); )
            {
               ConfigElement proxy_elt = (ConfigElement) e.next();
               ConfigElementPointer dev_ptr =
                  (ConfigElementPointer) proxy_elt.getProperty(DEVICE_PROPERTY,
                                                               0);
               if ( dev_ptr != null &&
                    dev_ptr.getTarget().equals(devElt.getName()) )
               {
                  proxy_count++;
               }
            }
            DefaultUnitPropertyHandler.addArtificialUnits(unit_map, unit_type,
                                                          proxy_count);
         }
      }
      DefaultGraphCell cell =
         createBaseDeviceCell(new DeviceInfo(devElt, context, unit_map),
                              attributes, x, y, false);
      for ( Iterator t = unit_map.keySet().iterator(); t.hasNext(); )
      {
         Integer type = (Integer) t.next();
         Integer proxy_count = (Integer) unit_map.get(type);
         addDevicePorts(cell, type, proxy_count.intValue());
      }
      return cell;
   }
   /**
    * Creates a basic device graph cell by creating an attribute map using
    * <code>org.vrjuggler.vrjconfig.commoneditors.DeviceGraph.createDeviceAttributes()</code>
    * and the given parameters.  The freshly created attribute map is stored
    * in the given attribute map using the new <code>DefaultGraphCell</code>
    * instance as its key.  In general, user code should not be using this
    * method directly, but it is made public so that instances of
    * <code>DeviceGraphCellCreator</code> can utilize it when necessary.
    *
    * @param devInfo    the informational object describing the device
    * @param attributes the attribute map where the vertex cell's default
    *                   attribute map will be stored by this function
    * @param x          the X coordinate for the initial positionaing of the
    *                   new vertex
    * @param y          the Y coordinate for the initial positionaing of the
    *                   new vertex
    * @param autoSize   flag indicating whether the new cell should be
    *                   auto-sized
    *
    * @see org.vrjuggler.vrjconfig.commoneditors.DeviceGraph#createDeviceAttributes(int,int,boolean)
    * @see DeviceGraphCellCreator
    * @see org.jgraph.graph.GraphConstants
    * @see org.jgraph.graph.AttributeMap
    */
   public static DefaultGraphCell createBaseDeviceCell(BaseDeviceInfo devInfo,
                                                       Map attributes,
                                                       int x, int y,
                                                       boolean autoSize)
   {
      DefaultGraphCell dev_cell = new DefaultGraphCell(devInfo);
      attributes.put(dev_cell, DeviceGraph.createDeviceAttributes(x, y,
                                                                  autoSize));
      return dev_cell;
   }
   /**
    * Adds the given number of ports to the given graph cell as children.
    * The ports are all created using
    * <code>createDevicePort(Integer,int)</code>.
    *
    * @param cell       the device graph cell to which the ports will be
    *                   added
    * @param unitType   the type of the input source (unit) for the new
    *                   ports
    * @param numUnits   the number of ports that will be addded
    *
    * @see #createDevicePort(Integer,int)
    */
   public static void addDevicePorts(DefaultGraphCell cell, Integer unitType,
                                     int numUnits)
   {
      for ( int i = 0; i < numUnits; ++i )
      {
         cell.add(createDevicePort(unitType, i));
      }
   }
   /**
    * Creates a new graph cell for the given config element that is used to
    * configure a device proxy.  The parameters to use for creating the
    * appropriate <code>DefaultGraphCell</code> (with its ports) are
    * determined based on the type of the config element passed in.  This
    * method is intended to be used for ensuring correct and easy graph cell
    * creation for config elements used to configure proxies.  However, the
    * config element type must be known <i>a priori</i> in order for this
    * method to be able to do its job.
    *
    * @param proxyElt           the config element for the device proxy being
    *                           represented by the vertex cell to be created
    * @param context            the config context where <code>proxyElt</code>
    *                           exists
    * @param aliases            all the aliases (zero or more) that exist for
    *                           <code>proxyElt</code>
    * @param attributes         the attribute map where the vertex cell's
    *                           default attribute map will be stored by this
    *                           function
    *
    * @throws IllegalArgumentException
    *   thrown when the type of <code>proxyElt</code> is unknown to this
    *   method, thus preventing correct creation of a
    *   <code>DefaultGraphCell</code> instance.
    */
   public static DefaultGraphCell createProxyCell(ConfigElement proxyElt,
                                                  ConfigContext context,
                                                  List aliases,
                                                  Map attributes)
   {
      ConfigDefinition def = proxyElt.getDefinition();
      DefaultGraphCell cell = null;
      // XXX: Come up with a better system for setting the x and y values.
      int x = 120, y = 20;
      if ( def.isOfType(PROXY_TYPE) )
      {
         cell = createProxyCell(proxyElt, context, aliases, attributes, x, y,
                                false);
      }
      else
      {
         throw new IllegalArgumentException("Unexpected definition " +
                                            def.getToken());
      }
      return cell;
   }
   /**
    * Creates a graph cell for a device proxy that has a single port as a
    * child.  The initial attribute map used for the graph cell is created
    * using
    * <code>org.vrjuggler.vrjconfig.commoneditors.DeviceGraph.createProxyAttributes()</code>,
    * and it is stored in the given attribute map.
    *
    * @param proxyElt           the config element for the device proxy being
    *                           represented by the vertex cell to be created
    * @param context            the config context where <code>proxyElt</code>
    *                           exists
    * @param aliases            all the aliases (zero or more) that exist for
    *                           <code>proxyElt</code>
    * @param attributes         the attribute map where the vertex cell's
    *                           default attribute map will be stored by this
    *                           function
    * @param x                  the X coordinate for the initial positionaing
    *                           of the new vertex
    * @param y                  the Y coordinate for the initial positionaing
    *                           of the new vertex
    * @param autoSize           flag indicating whether the new cell should be
    *                           auto-sized
    *
    * @see org.vrjuggler.vrjconfig.commoneditors.DeviceGraph#createProxyAttributes(int,int,boolean)
    */
   public static DefaultGraphCell createProxyCell(ConfigElement proxyElt,
                                                  ConfigContext context,
                                                  List aliases,
                                                  Map attributes, int x,
                                                  int y, boolean autoSize)
   {
      DefaultGraphCell proxy_cell =
         new DefaultGraphCell(new ProxyInfo(proxyElt, context, aliases));
      proxy_cell.add(new DefaultPort());
      attributes.put(proxy_cell,
                     DeviceGraph.createProxyAttributes(x, y, autoSize));
      return proxy_cell;
   }
   /**
    * Creates a connection between <code>proxyCell</code> and
    * <code>deviceCell</code> using the appropriate port in
    * <code>deviceCell</code>.  The port to use is determined by the user
    * object contained in <code>proxyCell</code>, which must be of type
    * <code>ProxyInfo</code>.  The proxy cell's user object will contain the
    * <code>ConfigElement</code> for the proxy, which in turn provides a unit
    * number for the device to which the proxy should refer.  The proxy config
    * element and the device config element will remain unchanged.
    *
    * @throws NoSuchPortException thrown If the two cells cannot be connected
    *                             because no appropriate port exists in
    *                             <code>deviceCell</code>
    *
    * @see ProxyInfo
    * @see #createProxyCell(ConfigElement,ConfigContext,List,Map,int,int,boolean)
    */
   public static DefaultEdge connectProxyToDevice(DefaultGraphCell proxyCell,
                                                  DefaultGraphCell deviceCell,
                                                  ConnectionSet cs,
                                                  Map attributes)
      throws NoSuchPortException
   {
      ProxyToDeviceEdge edge = null;


Please complete the code given below. 
/********
 * This file is part of Ext.NET.
 *     
 * Ext.NET is free software: you can redistribute it and/or modify
 * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * Ext.NET is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
 * 
 * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
 * along with Ext.NET.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * @version   : 1.2.0 - Ext.NET Pro License
 * @author    : Ext.NET, Inc. http://www.ext.net/
 * @date      : 2011-09-12
 * @copyright : Copyright (c) 2006-2011, Ext.NET, Inc. (http://www.ext.net/). All rights reserved.
 * @license   : GNU AFFERO GENERAL PUBLIC LICENSE (AGPL) 3.0. 
 *              See license.txt and http://www.ext.net/license/.
 *              See AGPL License at http://www.gnu.org/licenses/agpl-3.0.txt
 ********/
using System;
using System.ComponentModel;
using System.IO;
using System.Web.UI;
using Newtonsoft.Json;
using Ext.Net.Utilities;
namespace Ext.Net
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Meta]
    [Description("")]
    public abstract partial class MultiSelectBase<T> : Field, IStore where T : StateManagedItem 
    {
        /// <summary>
        /// The data store to use.
        /// </summary>
        [Meta]
        [ConfigOption("store", JsonMode.ToClientID)]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [IDReferenceProperty(typeof(Store))]
        [Description("The data store to use.")]
        public virtual string StoreID
        {
            get
            {
                return (string)this.ViewState["StoreID"] ?? "";
            }
            set
            {
                this.ViewState["StoreID"] = value;
            }
        }
        private StoreCollection store;
        /// <summary>
        ///  The data store to use.
        /// </summary>
        [Meta]
        [ConfigOption("store>Primary")]
        [Category("7. MultiSelect")]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [Description("The data store to use.")]
        public virtual StoreCollection Store
        {
            get
            {
                if (this.store == null)
                {
                    this.store = new StoreCollection();
                    this.store.AfterItemAdd += this.AfterStoreAdd;
                    this.store.AfterItemRemove += this.AfterStoreRemove;
                }
                return this.store;
            }
        }
		/// <summary>
		/// 
		/// </summary>
		[Description("")]
        protected virtual void AfterStoreAdd(Store item)
        {
            this.Controls.AddAt(0, item);
            this.LazyItems.Insert(0, item);
        }
		/// <summary>
		/// 
		/// </summary>
		[Description("")]
        protected virtual void AfterStoreRemove(Store item)
        {
            this.Controls.Remove(item);
            this.LazyItems.Remove(item);
        }
        private ListItemCollection<T> items;
        /// <summary>
        /// 
        /// </summary>
        [Meta]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [ViewStateMember]
        [Description("")]
        public ListItemCollection<T> Items
        {
            get
            {
                if (this.items == null)
                {
                    this.items = new ListItemCollection<T>();
                }
                return this.items;
            }
        }
		/// <summary>
		/// 
		/// </summary>
        [ConfigOption("store", JsonMode.Raw)]
        [DefaultValue("")]
		[Description("")]
        protected string ItemsProxy
        {
            get
            {
                if (this.StoreID.IsNotEmpty() || this.Store.Primary != null)
                {
                    return "";
                }
                return this.ItemsToStore;
            }
        }
        private string ItemsToStore
        {
            get
            {
                StringWriter sw = new StringWriter();
                JsonTextWriter jw = new JsonTextWriter(sw);
                ListItemCollectionJsonConverter converter = new ListItemCollectionJsonConverter();
                converter.WriteJson(jw, this.Items, null);
                return sw.GetStringBuilder().ToString();
            }
        }
        private SelectedListItemCollection selectedItems;
        /// <summary>
        /// 
        /// </summary>
        [Meta]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [ViewStateMember]
        [Description("")]
        public SelectedListItemCollection SelectedItems
        {
            get
            {
                if (this.selectedItems == null)
                {
                    this.selectedItems = new SelectedListItemCollection();
                }
                return this.selectedItems;
            }
        }
        /// <summary>
        /// The underlying data field name to bind to this MultiSelect.
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Description("The underlying data field name to bind to this MultiSelect.")]
        public virtual string DisplayField
        {
            get
            {
                return (string)this.ViewState["DisplayField"] ?? "text";
            }
            set
            {
                this.ViewState["DisplayField"] = value;
            }
        }
        /// <summary>
        /// The underlying data value name to bind to this MultiSelect.
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Description("The underlying data value name to bind to this MultiSelect.")]
        public virtual string ValueField
        {
            get
            {
                return (string)this.ViewState["ValueField"] ?? "value";
            }
            set
            {
                this.ViewState["ValueField"] = value;
            }
        }
        /// <summary>
        /// False to validate that the value length > 0 (defaults to true).
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue(true)]
        [Description("False to validate that the value length > 0 (defaults to true).")]
        public virtual bool AllowBlank
        {
            get
            {
                object obj = this.ViewState["AllowBlank"];
                return (obj == null) ? true : (bool)obj;
            }
            set
            {
                this.ViewState["AllowBlank"] = value;
            }
        }
        /// <summary>
        /// Maximum input field length allowed (defaults to Number.MAX_VALUE).
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue(-1)]
        [Description("Maximum input field length allowed (defaults to Number.MAX_VALUE).")]
        public virtual int MaxLength
        {
            get
            {
                object obj = this.ViewState["MaxLength"];
                return (obj == null) ? -1 : (int)obj;
            }
            set
            {
                this.ViewState["MaxLength"] = value;
            }
        }
        /// <summary>
        /// Minimum input field length required (defaults to 0).
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue(0)]
        [Description("Minimum input field length required (defaults to 0).")]
        public virtual int MinLength
        {
            get
            {
                object obj = this.ViewState["MinLength"];
                return (obj == null) ? 0 : (int)obj;
            }
            set
            {
                this.ViewState["MinLength"] = value;
            }
        }
        /// <summary>
        /// Error text to display if the maximum length validation fails (defaults to 'The maximum length for this field is {maxLength}').
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Localizable(true)]
        [Description("Error text to display if the maximum length validation fails (defaults to 'The maximum length for this field is {maxLength}').")]
        public virtual string MaxLengthText
        {
            get
            {
                return (string)this.ViewState["MaxLengthText"] ?? "";
            }
            set
            {
                this.ViewState["MaxLengthText"] = value;
            }
        }
        /// <summary>
        /// Error text to display if the minimum length validation fails (defaults to 'The minimum length for this field is {minLength}').
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Localizable(true)]
        [Description("Error text to display if the minimum length validation fails (defaults to 'The minimum length for this field is {minLength}').")]
        public virtual string MinLengthText
        {
            get
            {
                return (string)this.ViewState["MinLengthText"] ?? "";
            }
            set
            {
                this.ViewState["MinLengthText"] = value;
            }
        }
        /// <summary>
        /// Error text to display if the allow blank validation fails (defaults to 'This field is required').
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Localizable(true)]
        [Description("Error text to display if the allow blank validation fails (defaults to 'This field is required').")]
        public virtual string BlankText
        {
            get
            {
                return (string)this.ViewState["BlankText"] ?? "";
            }
            set
            {
                this.ViewState["BlankText"] = value;
            }
        }
        /// <summary>
        /// Causes drag operations to copy nodes rather than move (defaults to false).
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue(false)]
        [Description("Causes drag operations to copy nodes rather than move (defaults to false).")]
        public virtual bool Copy
        {
            get
            {
                object obj = this.ViewState["Copy"];
                return (obj == null) ? false : (bool)obj;
            }
            set
            {
                this.ViewState["Copy"] = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        [Meta]
        [ConfigOption("allowDup")]
        [Category("6. MultiSelect")]
        [DefaultValue(false)]
        [Description("")]
        public virtual bool AllowDuplicates
        {
            get
            {
                object obj = this.ViewState["AllowDuplicates"];
                return (obj == null) ? false : (bool)obj;
            }
            set
            {
                this.ViewState["AllowDuplicates"] = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue(false)]
        [Description("")]
        public virtual bool AllowTrash
        {
            get
            {
                object obj = this.ViewState["AllowTrash"];
                return (obj == null) ? false : (bool)obj;
            }
            set
            {
                this.ViewState["AllowTrash"] = value;
            }
        }
        /// <summary>
        /// The title text to display in the panel header (defaults to '')
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Description("The title text to display in the panel header (defaults to '')")]
        public virtual string Legend
        {
            get
            {
                return (string)this.ViewState["Legend"] ?? "";
            }
            set
            {
                this.ViewState["Legend"] = value;
            }
        }
        /// <summary>
        /// The string used to delimit between items when set or returned as a string of values
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue(",")]
        [Description("The string used to delimit between items when set or returned as a string of values")]
        public virtual string Delimiter
        {
            get
            {
                return (string)this.ViewState["Delimiter"] ?? ",";
            }
            set
            {
                this.ViewState["Delimiter"] = value;
            }
        }
        /// <summary>
        /// The ddgroup name(s) for the View's DragZone (defaults to undefined).
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Description("The ddgroup name(s) for the View's DragZone (defaults to undefined).")]
        public virtual string DragGroup
        {
            get
            {
                return (string)this.ViewState["DragGroup"] ?? "";
            }
            set
            {
                this.ViewState["DragGroup"] = value;
            }
        }
        /// <summary>
        /// The ddgroup name(s) for the View's DropZone (defaults to undefined).
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Description("The ddgroup name(s) for the View's DropZone (defaults to undefined).")]
        public virtual string DropGroup
        {
            get
            {
                return (string)this.ViewState["DropGroup"] ?? "";
            }
            set
            {
                this.ViewState["DropGroup"] = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue(false)]
        [Description("")]
        public virtual bool AppendOnly
        {
            get
            {
                object obj = this.ViewState["AppendOnly"];
                return (obj == null) ? false : (bool)obj;
            }
            set
            {
                this.ViewState["AppendOnly"] = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue("")]
        [Description("")]
        public virtual string SortField
        {
            get
            {
                return (string)this.ViewState["SortField"] ?? "";
            }
            set
            {
                this.ViewState["SortField"] = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        [Meta]
        [ConfigOption(JsonMode.ToLower)]
        [DefaultValue(SortDirection.ASC)]
        [NotifyParentProperty(true)]
        [Description("")]
        public SortDirection Direction
        {
            get
            {
                object obj = this.ViewState["Direction"];
                return (obj == null) ? SortDirection.ASC : (SortDirection)obj;
            }
            set
            {
                this.ViewState["Direction"] = value;
            }
        }
        /// <summary>
        /// True to submit text of selected items
        /// </summary>
        [Meta]
        [ConfigOption]
        [Category("6. MultiSelect")]
        [DefaultValue(true)]
        [Description("True to submit text of selected items")]
        public virtual bool SubmitText
        {
            get
            {


Please complete the code given below. 
"""Imports:
    defaultdict: for multidimensional dictionaries (implicitly instantiating
        the nested dictionaries as the dimensions are accessed)
    operator: sorting dictionaries
    os: writing the collection out to disk
"""
from collections import defaultdict
import operator
import os
class TrackCollection(object):
    """A structure sorting tracks by artist and album
    Attributes:
        file_count: int number of files in this collection
        collection: 2-dimensional defaultdict of all tracks namespaced by artist
            then album
    """
    file_count = 0
    def __init__(self):
        def create_multidimensional_dict(n, dict_type):
            """Recursive function to create a multidimensional defaultdict
            Args:
                n: int dimensionality of the defaultdict
                dict_type: type of the elements
            Returns:
                A multidimensional defaultdict"""
            if n < 1:
                return dict_type()
            return defaultdict(lambda: create_multidimensional_dict(n-1, dict_type))
        # Create one.
        self.collection = create_multidimensional_dict(2, list)
    def __str__(self):
        s = "---- Album Dictionary Mappings ----\n"
        # List artists and sort
        artists = self.collection.keys()
        artists.sort()
        for artist in artists:
            # List albums and sort
            albums = self.collection[artist].keys()
            albums.sort(key=lambda k2, k1=artist: self.collection[k1][k2][0].final.year)
            for album in albums:
                s += "[%s][%s]\n" % (artist, album)
                for song in self.collection[artist][album]:
                    s += "  %02d %s\n" % (song.final.track, song.final.title)
        s += "-----------------------------------"
        return s
    def add(self, track):
        """Adds a TrackFile to the collection.
        Args:
            track: A TrackFile to add. Must be finalised at this point (for
                indexing purposes).
        Returns:
            None
        Raises:
            Exception: The given track was not finalised.
        """
        # TODO Compilations are going to wreak havoc here too, see note on
        # remove_duplicates.
        if not track.finalised:
            raise Exception("TrackCollection cannot add a non-finalised track")
        if not self.collection[track.final.artist][track.final.album]:
            self.collection[track.final.artist][track.final.album] = []
        self.collection[track.final.artist][track.final.album].append(track)
        self.file_count += 1
    def remove_duplicates(self, warnings=None, report_progress=None):
        """Look for duplicate songs and remove them.
        Duplicate artists and albums are not a problem - you need a music file
        (itself a song) to contain the data to have generated them, so you
        either have duplicate songs, or different songs with slightly different
        artist/album names. This should be corrected by the TrackFile's
        compression step. If it wasn't properly picked up then (i.e. the names
        were too dissimilar) we have no further information at this point so we
        can't fix it.
        Args:
            report_progress: Optional two argument function to report progress
                where the first argument is the total number of items and the
                second argument is the completed number of items.
        Returns:
            None
        """
        # TODO: Compilations are going to go crazy here... revist this later,
        # probably with a TrackFile flag for (probable) compilation tracks.
        processed_count = 0
        for artist in self.collection:
            for album in self.collection[artist]:
                duplicate_tracker = {}
                to_be_removed = []
                for song in self.collection[artist][album]:
                    title = song.final.title
                    # If a track with this title already exists within this
                    # artist/album tuple, mark it as a duplicate (and optionally
                    # generate a warning
                    if title in duplicate_tracker:
                        duplicate = duplicate_tracker[title]
                        if warnings is not None and ( \
                                duplicate.final.track != song.final.track or \
                                duplicate.final.year != song.final.year):
                            warnings.append('Found songs with the same artist, ' \
                                'album and title but differing track or year:\n' \
                                '  %s\n    %s\n  %s\n    %s' % ( \
                                    duplicate, duplicate.file_path, \
                                    song, song.file_path))
                        to_be_removed.append(song)
                    else:
                        duplicate_tracker[title] = song
                    processed_count += 1
                    if report_progress:
                        report_progress(self.file_count, processed_count)
                for song in to_be_removed:
                    self.collection[artist][album].remove(song)
                self.file_count -= len(to_be_removed)
    def standardise_album_tracks(self, warnings=None, report_progress=None):
        """Standardises track data between tracks within each album.
        Takes a vote between tracks within albums to standardise information on
        the album year and track numbering.
        Args:
            report_progress: Optional two argument function to report progress
                where the first argument is the total number of items and the
                second argument is the completed number of items.
        Returns:
            None
        """
        # TODO Compilations are going to wreak havoc here too, see note on
        # remove_duplicates.
        processed_count = 0
        for artist in self.collection:
            for album in self.collection[artist]:
                # First collect the number of times each different album year
                # data appears. Ideally all tracks should have the same year.
                album_year_votes = {}
                for song in self.collection[artist][album]:
                    if song.final.year in album_year_votes:
                        album_year_votes[song.final.year] += 1
                    else:
                        album_year_votes[song.final.year] = 1
                    processed_count += 1
                    if report_progress:
                        report_progress(self.file_count, processed_count)
                # If there is more than one album year listed, standardise. A
                # good argument could be made for any number of strategies for
                # standardising. Currently the majority vote takes it, but the
                # latest 'sensible' year would also be an idea.
                if len(album_year_votes.keys()) > 1:
                    sorted_album_year_votes = sorted(album_year_votes.iteritems(),
                                                     key=operator.itemgetter(1),
                                                     reverse=True)
                    if sorted_album_year_votes[0][0] != 0:
                        correct_year = sorted_album_year_votes[0][0]
                    else:
                        correct_year = sorted_album_year_votes[1][0]
                    if warnings is not None:
                        warnings.append('Multiple album years for %s ' \
                            'by %s: %s. Using %d.' \
                            % (album, artist, str(sorted_album_year_votes), correct_year))
                    for song in self.collection[artist][album]:
                        song.final.year = correct_year
    def sort_songs_by_track(self):
        """Sort the songs in the lists by their track numbers.
        Returns:
            None
        """
        for artist in self.collection:
            for album in self.collection[artist]:
                self.collection[artist][album].sort(key=lambda x: x.final.track)
    def create_new_filesystem(self, new_path):
        """Creates a collection starting from a root directory.
        Args:
            new_path: The path to recursively search for the collection within.
        Returns:
            None
        """
        os.mkdir(new_path)
        for artist in self.collection:
            artist_subpath = '/%s' % (artist)
            os.mkdir(new_path + artist_subpath)
            for album in self.collection[artist]:
                if self.collection[artist][album][0].final.year != 0:
                    album_subpath = '/[%d] %s' % (self.collection[artist][album][0].final.year, album)
                else:
                    album_subpath = '/%s' % (album)
                os.mkdir(new_path + artist_subpath + album_subpath)


Please complete the code given below. 
/*
 * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package java.lang;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ResolvedModule;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.loader.ClassLoaderValue;
import jdk.internal.loader.Loader;
import jdk.internal.loader.LoaderPool;
import jdk.internal.module.ServicesCatalog;
import sun.security.util.SecurityConstants;
/**
 * A layer of modules in the Java virtual machine.
 *
 * <p> A layer is created from a graph of modules in a {@link Configuration}
 * and a function that maps each module to a {@link ClassLoader}.
 * Creating a layer informs the Java virtual machine about the classes that
 * may be loaded from the modules so that the Java virtual machine knows which
 * module that each class is a member of. </p>
 *
 * <p> Creating a layer creates a {@link Module} object for each {@link
 * ResolvedModule} in the configuration. For each resolved module that is
 * {@link ResolvedModule#reads() read}, the {@code Module} {@link
 * Module#canRead reads} the corresponding run-time {@code Module}, which may
 * be in the same layer or a {@link #parents() parent} layer. </p>
 *
 * <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
 * {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
 * provide convenient ways to create a module layer where all modules are
 * mapped to a single class loader or where each module is mapped to its own
 * class loader. The {@link #defineModules defineModules} method is for more
 * advanced cases where modules are mapped to custom class loaders by means of
 * a function specified to the method. Each of these methods has an instance
 * and static variant. The instance methods create a layer with the receiver
 * as the parent layer. The static methods are for more advanced cases where
 * there can be more than one parent layer or where a {@link
 * ModuleLayer.Controller Controller} is needed to control modules in the layer
 * </p>
 *
 * <p> A Java virtual machine has at least one non-empty layer, the {@link
 * #boot() boot} layer, that is created when the Java virtual machine is
 * started. The boot layer contains module {@code java.base} and is the only
 * layer in the Java virtual machine with a module named "{@code java.base}".
 * The modules in the boot layer are mapped to the bootstrap class loader and
 * other class loaders that are <a href="ClassLoader.html#builtinLoaders">
 * built-in</a> into the Java virtual machine. The boot layer will often be
 * the {@link #parents() parent} when creating additional layers. </p>
 *
 * <p> Each {@code Module} in a layer is created so that it {@link
 * Module#isExported(String) exports} and {@link Module#isOpen(String) opens}
 * the packages described by its {@link ModuleDescriptor}. Qualified exports
 * (where a package is exported to a set of target modules rather than all
 * modules) are reified when creating the layer as follows: </p>
 * <ul>
 *     <li> If module {@code X} exports a package to {@code Y}, and if the
 *     runtime {@code Module} {@code X} reads {@code Module} {@code Y}, then
 *     the package is exported to {@code Module} {@code Y} (which may be in
 *     the same layer as {@code X} or a parent layer). </li>
 *
 *     <li> If module {@code X} exports a package to {@code Y}, and if the
 *     runtime {@code Module} {@code X} does not read {@code Y} then target
 *     {@code Y} is located as if by invoking {@link #findModule(String)
 *     findModule} to find the module in the layer or its parent layers. If
 *     {@code Y} is found then the package is exported to the instance of
 *     {@code Y} that was found. If {@code Y} is not found then the qualified
 *     export is ignored. </li>
 * </ul>
 *
 * <p> Qualified opens are handled in same way as qualified exports. </p>
 *
 * <p> As when creating a {@code Configuration},
 * {@link ModuleDescriptor#isAutomatic() automatic} modules receive special
 * treatment when creating a layer. An automatic module is created in the
 * Java virtual machine as a {@code Module} that reads every unnamed {@code
 * Module} in the Java virtual machine. </p>
 *
 * <p> Unless otherwise specified, passing a {@code null} argument to a method
 * in this class causes a {@link NullPointerException NullPointerException} to
 * be thrown. </p>
 *
 * <h3> Example usage: </h3>
 *
 * <p> This example creates a configuration by resolving a module named
 * "{@code myapp}" with the configuration for the boot layer as the parent. It
 * then creates a new layer with the modules in this configuration. All modules
 * are defined to the same class loader. </p>
 *
 * <pre>{@code
 *     ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
 *
 *     ModuleLayer parent = ModuleLayer.boot();
 *
 *     Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
 *
 *     ClassLoader scl = ClassLoader.getSystemClassLoader();
 *
 *     ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
 *
 *     Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
 * }</pre>
 *
 * @since 9
 * @spec JPMS
 * @see Module#getLayer()
 */
public final class ModuleLayer {
    // the empty layer
    private static final ModuleLayer EMPTY_LAYER
        = new ModuleLayer(Configuration.empty(), List.of(), null);
    // the configuration from which this layer was created
    private final Configuration cf;
    // parent layers, empty in the case of the empty layer
    private final List<ModuleLayer> parents;
    // maps module name to jlr.Module
    private final Map<String, Module> nameToModule;
    /**
     * Creates a new module layer from the modules in the given configuration.
     */
    private ModuleLayer(Configuration cf,
                        List<ModuleLayer> parents,
                        Function<String, ClassLoader> clf)
    {
        this.cf = cf;
        this.parents = parents; // no need to do defensive copy
        Map<String, Module> map;
        if (parents.isEmpty()) {
            map = Map.of();
        } else {
            map = Module.defineModules(cf, clf, this);
        }
        this.nameToModule = map; // no need to do defensive copy
    }
    /**
     * Controls a module layer. The static methods defined by {@link ModuleLayer}
     * to create module layers return a {@code Controller} that can be used to
     * control modules in the layer.
     *
     * <p> Unless otherwise specified, passing a {@code null} argument to a
     * method in this class causes a {@link NullPointerException
     * NullPointerException} to be thrown. </p>
     *
     * @apiNote Care should be taken with {@code Controller} objects, they
     * should never be shared with untrusted code.
     *
     * @since 9
     * @spec JPMS
     */
    public static final class Controller {
        private final ModuleLayer layer;
        Controller(ModuleLayer layer) {
            this.layer = layer;
        }
        /**
         * Returns the layer that this object controls.
         *
         * @return the module layer
         */
        public ModuleLayer layer() {
            return layer;
        }
        private void ensureInLayer(Module source) {
            if (source.getLayer() != layer)
                throw new IllegalArgumentException(source + " not in layer");
        }
        /**
         * Updates module {@code source} in the layer to read module
         * {@code target}. This method is a no-op if {@code source} already
         * reads {@code target}.
         *
         * @implNote <em>Read edges</em> added by this method are <em>weak</em>
         * and do not prevent {@code target} from being GC'ed when {@code source}
         * is strongly reachable.
         *
         * @param  source
         *         The source module
         * @param  target
         *         The target module to read
         *
         * @return This controller
         *
         * @throws IllegalArgumentException
         *         If {@code source} is not in the module layer
         *
         * @see Module#addReads
         */
        public Controller addReads(Module source, Module target) {
            ensureInLayer(source);
            source.implAddReads(target);
            return this;
        }
        /**
         * Updates module {@code source} in the layer to export a package to
         * module {@code target}. This method is a no-op if {@code source}
         * already exports the package to at least {@code target}.
         *
         * @param  source
         *         The source module
         * @param  pn
         *         The package name
         * @param  target
         *         The target module
         *
         * @return This controller
         *
         * @throws IllegalArgumentException
         *         If {@code source} is not in the module layer or the package
         *         is not in the source module
         *
         * @see Module#addExports
         */
        public Controller addExports(Module source, String pn, Module target) {
            ensureInLayer(source);
            source.implAddExports(pn, target);
            return this;
        }
        /**
         * Updates module {@code source} in the layer to open a package to
         * module {@code target}. This method is a no-op if {@code source}
         * already opens the package to at least {@code target}.
         *
         * @param  source
         *         The source module
         * @param  pn
         *         The package name
         * @param  target
         *         The target module
         *
         * @return This controller
         *
         * @throws IllegalArgumentException
         *         If {@code source} is not in the module layer or the package
         *         is not in the source module
         *
         * @see Module#addOpens
         */
        public Controller addOpens(Module source, String pn, Module target) {
            ensureInLayer(source);
            source.implAddOpens(pn, target);
            return this;
        }
    }
    /**
     * Creates a new module layer, with this layer as its parent, by defining the
     * modules in the given {@code Configuration} to the Java virtual machine.
     * This method creates one class loader and defines all modules to that
     * class loader. The {@link ClassLoader#getParent() parent} of each class
     * loader is the given parent class loader. This method works exactly as
     * specified by the static {@link
     * #defineModulesWithOneLoader(Configuration,List,ClassLoader)
     * defineModulesWithOneLoader} method when invoked with this layer as the
     * parent. In other words, if this layer is {@code thisLayer} then this
     * method is equivalent to invoking:
     * <pre> {@code
     *     ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
     * }</pre>
     *
     * @param  cf
     *         The configuration for the layer
     * @param  parentLoader
     *         The parent class loader for the class loader created by this
     *         method; may be {@code null} for the bootstrap class loader
     *
     * @return The newly created layer
     *
     * @throws IllegalArgumentException
     *         If the given configuration has more than one parent or the parent
     *         of the configuration is not the configuration for this layer
     * @throws LayerInstantiationException
     *         If the layer cannot be created for any of the reasons specified
     *         by the static {@code defineModulesWithOneLoader} method
     * @throws SecurityException
     *         If {@code RuntimePermission("createClassLoader")} or
     *         {@code RuntimePermission("getClassLoader")} is denied by
     *         the security manager
     *
     * @see #findLoader
     */
    public ModuleLayer defineModulesWithOneLoader(Configuration cf,
                                                  ClassLoader parentLoader) {
        return defineModulesWithOneLoader(cf, List.of(this), parentLoader).layer();
    }
    /**
     * Creates a new module layer, with this layer as its parent, by defining the
     * modules in the given {@code Configuration} to the Java virtual machine.
     * Each module is defined to its own {@link ClassLoader} created by this
     * method. The {@link ClassLoader#getParent() parent} of each class loader
     * is the given parent class loader. This method works exactly as specified
     * by the static {@link
     * #defineModulesWithManyLoaders(Configuration,List,ClassLoader)
     * defineModulesWithManyLoaders} method when invoked with this layer as the
     * parent. In other words, if this layer is {@code thisLayer} then this
     * method is equivalent to invoking:
     * <pre> {@code
     *     ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
     * }</pre>
     *
     * @param  cf
     *         The configuration for the layer
     * @param  parentLoader
     *         The parent class loader for each of the class loaders created by
     *         this method; may be {@code null} for the bootstrap class loader
     *
     * @return The newly created layer
     *
     * @throws IllegalArgumentException
     *         If the given configuration has more than one parent or the parent
     *         of the configuration is not the configuration for this layer
     * @throws LayerInstantiationException
     *         If the layer cannot be created for any of the reasons specified
     *         by the static {@code defineModulesWithManyLoaders} method
     * @throws SecurityException
     *         If {@code RuntimePermission("createClassLoader")} or
     *         {@code RuntimePermission("getClassLoader")} is denied by
     *         the security manager
     *
     * @see #findLoader
     */
    public ModuleLayer defineModulesWithManyLoaders(Configuration cf,
                                                    ClassLoader parentLoader) {
        return defineModulesWithManyLoaders(cf, List.of(this), parentLoader).layer();
    }
    /**
     * Creates a new module layer, with this layer as its parent, by defining the
     * modules in the given {@code Configuration} to the Java virtual machine.
     * Each module is mapped, by name, to its class loader by means of the
     * given function. This method works exactly as specified by the static
     * {@link #defineModules(Configuration,List,Function) defineModules}
     * method when invoked with this layer as the parent. In other words, if
     * this layer is {@code thisLayer} then this method is equivalent to
     * invoking:
     * <pre> {@code
     *     ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
     * }</pre>
     *
     * @param  cf
     *         The configuration for the layer
     * @param  clf
     *         The function to map a module name to a class loader
     *
     * @return The newly created layer
     *
     * @throws IllegalArgumentException
     *         If the given configuration has more than one parent or the parent
     *         of the configuration is not the configuration for this layer
     * @throws LayerInstantiationException
     *         If the layer cannot be created for any of the reasons specified
     *         by the static {@code defineModules} method
     * @throws SecurityException
     *         If {@code RuntimePermission("getClassLoader")} is denied by
     *         the security manager
     */
    public ModuleLayer defineModules(Configuration cf,
                                     Function<String, ClassLoader> clf) {
        return defineModules(cf, List.of(this), clf).layer();
    }
    /**
     * Creates a new module layer by defining the modules in the given {@code
     * Configuration} to the Java virtual machine. This method creates one
     * class loader and defines all modules to that class loader.
     *
     * <p> The class loader created by this method implements <em>direct
     * delegation</em> when loading classes from modules. If the {@link
     * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
     * load a class then it uses the package name of the class to map it to a
     * module. This may be a module in this layer and hence defined to the same
     * class loader. It may be a package in a module in a parent layer that is
     * exported to one or more of the modules in this layer. The class
     * loader delegates to the class loader of the module, throwing {@code
     * ClassNotFoundException} if not found by that class loader.
     * When {@code loadClass} is invoked to load classes that do not map to a
     * module then it delegates to the parent class loader. </p>
     *
     * <p> The class loader created by this method locates resources
     * ({@link ClassLoader#getResource(String) getResource}, {@link
     * ClassLoader#getResources(String) getResources}, and other resource
     * methods) in all modules in the layer before searching the parent class
     * loader. </p>
     *
     * <p> Attempting to create a layer with all modules defined to the same
     * class loader can fail for the following reasons:
     *
     * <ul>
     *
     *     <li><p> <em>Overlapping packages</em>: Two or more modules in the
     *     configuration have the same package. </p></li>
     *
     *     <li><p> <em>Split delegation</em>: The resulting class loader would
     *     need to delegate to more than one class loader in order to load
     *     classes in a specific package. </p></li>
     *
     * </ul>
     *
     * <p> In addition, a layer cannot be created if the configuration contains
     * a module named "{@code java.base}", or a module contains a package named
     * "{@code java}" or a package with a name starting with "{@code java.}". </p>
     *
     * <p> If there is a security manager then the class loader created by
     * this method will load classes and resources with privileges that are
     * restricted by the calling context of this method. </p>
     *
     * @param  cf
     *         The configuration for the layer
     * @param  parentLayers
     *         The list of parent layers in search order
     * @param  parentLoader
     *         The parent class loader for the class loader created by this
     *         method; may be {@code null} for the bootstrap class loader
     *
     * @return A controller that controls the newly created layer
     *
     * @throws IllegalArgumentException
     *         If the parent(s) of the given configuration do not match the
     *         configuration of the parent layers, including order
     * @throws LayerInstantiationException
     *         If all modules cannot be defined to the same class loader for any
     *         of the reasons listed above
     * @throws SecurityException
     *         If {@code RuntimePermission("createClassLoader")} or
     *         {@code RuntimePermission("getClassLoader")} is denied by
     *         the security manager
     *
     * @see #findLoader
     */
    public static Controller defineModulesWithOneLoader(Configuration cf,
                                                        List<ModuleLayer> parentLayers,
                                                        ClassLoader parentLoader)
    {
        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
        checkConfiguration(cf, parents);
        checkCreateClassLoaderPermission();
        checkGetClassLoaderPermission();
        try {
            Loader loader = new Loader(cf.modules(), parentLoader);
            loader.initRemotePackageMap(cf, parents);
            ModuleLayer layer = new ModuleLayer(cf, parents, mn -> loader);
            return new Controller(layer);
        } catch (IllegalArgumentException | IllegalStateException e) {
            throw new LayerInstantiationException(e.getMessage());
        }
    }
    /**
     * Creates a new module layer by defining the modules in the given {@code
     * Configuration} to the Java virtual machine. Each module is defined to
     * its own {@link ClassLoader} created by this method. The {@link
     * ClassLoader#getParent() parent} of each class loader is the given parent
     * class loader.
     *
     * <p> The class loaders created by this method implement <em>direct
     * delegation</em> when loading classes from modules. If the {@link
     * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
     * load a class then it uses the package name of the class to map it to a
     * module. The package may be in the module defined to the class loader.
     * The package may be exported by another module in this layer to the
     * module defined to the class loader. It may be in a package exported by a
     * module in a parent layer. The class loader delegates to the class loader
     * of the module, throwing {@code ClassNotFoundException} if not found by
     * that class loader. When {@code loadClass} is invoked to load a class
     * that does not map to a module then it delegates to the parent class
     * loader. </p>
     *
     * <p> The class loaders created by this method locate resources
     * ({@link ClassLoader#getResource(String) getResource}, {@link
     * ClassLoader#getResources(String) getResources}, and other resource
     * methods) in the module defined to the class loader before searching
     * the parent class loader. </p>
     *
     * <p> If there is a security manager then the class loaders created by
     * this method will load classes and resources with privileges that are
     * restricted by the calling context of this method. </p>
     *
     * @param  cf
     *         The configuration for the layer
     * @param  parentLayers
     *         The list of parent layers in search order
     * @param  parentLoader
     *         The parent class loader for each of the class loaders created by
     *         this method; may be {@code null} for the bootstrap class loader
     *
     * @return A controller that controls the newly created layer
     *
     * @throws IllegalArgumentException
     *         If the parent(s) of the given configuration do not match the
     *         configuration of the parent layers, including order
     * @throws LayerInstantiationException
     *         If the layer cannot be created because the configuration contains
     *         a module named "{@code java.base}" or a module contains a package
     *         named "{@code java}" or a package with a name starting with
     *         "{@code java.}"
     *
     * @throws SecurityException
     *         If {@code RuntimePermission("createClassLoader")} or
     *         {@code RuntimePermission("getClassLoader")} is denied by
     *         the security manager
     *
     * @see #findLoader
     */
    public static Controller defineModulesWithManyLoaders(Configuration cf,
                                                          List<ModuleLayer> parentLayers,
                                                          ClassLoader parentLoader)
    {
        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
        checkConfiguration(cf, parents);
        checkCreateClassLoaderPermission();
        checkGetClassLoaderPermission();
        LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
        try {
            ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
            return new Controller(layer);
        } catch (IllegalArgumentException | IllegalStateException e) {
            throw new LayerInstantiationException(e.getMessage());
        }
    }
    /**
     * Creates a new module layer by defining the modules in the given {@code
     * Configuration} to the Java virtual machine. The given function maps each
     * module in the configuration, by name, to a class loader. Creating the
     * layer informs the Java virtual machine about the classes that may be
     * loaded so that the Java virtual machine knows which module that each
     * class is a member of.
     *
     * <p> The class loader delegation implemented by the class loaders must
     * respect module readability. The class loaders should be
     * {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to
     * avoid deadlocks during class loading. In addition, the entity creating
     * a new layer with this method should arrange that the class loaders be
     * ready to load from these modules before there are any attempts to load
     * classes or resources. </p>
     *
     * <p> Creating a layer can fail for the following reasons: </p>
     *
     * <ul>
     *
     *     <li><p> Two or more modules with the same package are mapped to the
     *     same class loader. </p></li>
     *
     *     <li><p> A module is mapped to a class loader that already has a
     *     module of the same name defined to it. </p></li>
     *
     *     <li><p> A module is mapped to a class loader that has already
     *     defined types in any of the packages in the module. </p></li>
     *
     * </ul>
     *
     * <p> In addition, a layer cannot be created if the configuration contains
     * a module named "{@code java.base}", a configuration contains a module
     * with a package named "{@code java}" or a package name starting with
     * "{@code java.}", or the function to map a module name to a class loader
     * returns {@code null} or the {@linkplain ClassLoader#getPlatformClassLoader()
     * platform class loader}. </p>
     *
     * <p> If the function to map a module name to class loader throws an error
     * or runtime exception then it is propagated to the caller of this method.
     * </p>
     *
     * @apiNote It is implementation specific as to whether creating a layer
     * with this method is an atomic operation or not. Consequentially it is
     * possible for this method to fail with some modules, but not all, defined
     * to the Java virtual machine.
     *
     * @param  cf
     *         The configuration for the layer
     * @param  parentLayers
     *         The list of parent layers in search order
     * @param  clf
     *         The function to map a module name to a class loader
     *
     * @return A controller that controls the newly created layer
     *
     * @throws IllegalArgumentException
     *         If the parent(s) of the given configuration do not match the
     *         configuration of the parent layers, including order
     * @throws LayerInstantiationException
     *         If creating the layer fails for any of the reasons listed above
     * @throws SecurityException
     *         If {@code RuntimePermission("getClassLoader")} is denied by
     *         the security manager
     */
    public static Controller defineModules(Configuration cf,
                                           List<ModuleLayer> parentLayers,
                                           Function<String, ClassLoader> clf)
    {
        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
        checkConfiguration(cf, parents);
        Objects.requireNonNull(clf);
        checkGetClassLoaderPermission();
        // The boot layer is checked during module system initialization
        if (boot() != null) {
            checkForDuplicatePkgs(cf, clf);
        }
        try {
            ModuleLayer layer = new ModuleLayer(cf, parents, clf);
            return new Controller(layer);
        } catch (IllegalArgumentException | IllegalStateException e) {
            throw new LayerInstantiationException(e.getMessage());
        }
    }
    /**
     * Checks that the parent configurations match the configuration of
     * the parent layers.
     */
    private static void checkConfiguration(Configuration cf,
                                           List<ModuleLayer> parentLayers)
    {
        Objects.requireNonNull(cf);
        List<Configuration> parentConfigurations = cf.parents();
        if (parentLayers.size() != parentConfigurations.size())
            throw new IllegalArgumentException("wrong number of parents");
        int index = 0;
        for (ModuleLayer parent : parentLayers) {
            if (parent.configuration() != parentConfigurations.get(index)) {
                throw new IllegalArgumentException(
                        "Parent of configuration != configuration of this Layer");
            }
            index++;
        }
    }
    private static void checkCreateClassLoaderPermission() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null)
            sm.checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
    }
    private static void checkGetClassLoaderPermission() {
