Categories
VB.NET Упътвания

Вграждане на dll в assembly

Примерен код на VB.Net

1. Добавяне на Event Handler преди извикване на ресурс от dll файла

AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf AssemblyResolve

2. Функция за извикване на dll файла

Private Function AssemblyResolve(ByVal sender As Object, ByVal e As ResolveEventArgs) As Assembly
Dim resourceFullName As String = String.Format("Seo.{0}.dll", e.Name.Split(","
  c)(0))
Dim thisAssembly As Assembly = Assembly.GetExecutingAssembly()
Using resource As Stream = thisAssembly.GetManifestResourceStream(resourceFullName)
If resource IsNot Nothing Then
Return Assembly.Load(ToBytes(resource))
End If
Return Nothing
End Using
End Function

Private Function ToBytes(ByVal instance As Stream) As Byte()
Dim capacity As Integer = If(instance.CanSeek, Convert.ToInt32(instance.Length), 0)

Using result As New MemoryStream(capacity)
Dim readLength As Integer
Dim buffer(4096) As Byte

Do
readLength = instance.Read(buffer, 0, buffer.Length)
result.Write(buffer, 0, readLength)
Loop While readLength > 0

Return result.ToArray()
End Using
End Function
Categories
Visual C#

Конвертиране на файлове в SDR

Програма за конвертиране на файлове с координати на точки в SDR формат

Повече за програмата:

ConvertToSDR

Връзка за сваляне:

Categories
VB.NET

TIN Surface

Поддържани изходни формати във версия 0.7

  • скриптов файл за AutoCAD – експортира повърхнината като 3D линии
  • ESRI Shape файл – за ArcGIS, QGIS и други ГИС програми
  • XML файл – поддържа се LandXML, експортират се точките и триъгълниците

Формат на входния файл

Пълен формат:

[point id] [north] [east] [elevation] [point code]

11415 4572370.166 9462415.219 112.055 road

Само North, East, Elevation

[north] [east] [elevation]

4572369.179 9462409.152 112.190

С Point ID

[point id] [north] [east] [elevation]

11415 4572370.166 9462415.219 112.055

За разделител се използва интервал.

Връзка за сваляне:

[download id=”1074″]

Визуализация на създадена повърхнина с триъгълници и върхове:

tin surface triangles with vertices

Повече за програмата: TIN

Categories
VB.NET

Създаване на TIN с MapWinGIS

Примерен код на VB.NET за създаване на TIN* модел с MapWinGIS

* TIN – Triangular Irregular Network, Нерегулярна мрежа от триъгълници

Dim utils As New Utils()
Dim tin As New Tin()
tin.CreateTinFromPoints(points.ToArray())
Dim shapefile As New Shapefile()
shapefile = utils.TinToShapefile(tin, ShpfileType.SHP_POLYGON)
Categories
AutoCAD Упътвания

Копиране на обекти от xref чертежи

С командата ncopy, също достъпна от меню Express -> Blocks, може да се копират обекти от външни референции на чертежи към текущия в AutoCAD.

Командата е много полезна при работа с xref обекти в AutoCAD.

Categories
ООП Телерик

Покана за присъствено обучение

Най-хубавото нещо след успешно положен и взет с отличие изпит в Софтуерната академия е покана за преминаване от онлайн в присъствена форма на обучение.

Признание, което заслужава всеки, получил отлична оценка 🙂

Categories
ООП Телерик

ООП – Взет с отличен!

Малко статистика от курса по ООП:

Курс: Обектно-ориентирано програмиране (ООП)

  • Резултат на изпита: 313 точки
  • Средно за изпита: 173 точки
  • MAX получени на изпита: 393 точки
  • MAX за изпита: 400 точки

Взет с отличие!
Точки: 48.13
Място: 224

Ниският резултат в крайното класиране се дължи на 15% бонус от домашните и 5% бонус от оценяването на 3 домашни на лекция, които не получих, както и бонуса от отборната работа, в която не участвах 🙂

Categories
Телерик

Резултат от изпита по ООП в BGCoder

Изпита по Обектно-ориентирано програмиране на C# приключи!

Резултът в BGCoder е място 22 от 258 в сутрешната група и точки 162 от 200!

Точките по задачи са:

– 100 / 100 на първа задача;

– 62 / 100 на втора задача.

В очакване на оценката от трейнърите в Академията 🙂

Categories
Visual C# ООП Телерик

Подготовка за изпита по ООП

War Machines

Решение

namespace WarMachines.Engine {
  using System;
  using System.Collections.Generic;
  using System.Linq;

  using WarMachines.Interfaces;

  public class Command: ICommand {
    private
    const char SplitCommandSymbol = ' ';

    private string name;
    private IList parameters;

    private Command(string input) {
      this.TranslateInput(input);
    }

    public string Name {
      get {
        return this.name;
      }

      private set {
        if (string.IsNullOrEmpty(value)) {
          throw new ArgumentNullException("Name cannot be null or empty.");
        }

        this.name = value;
      }
    }

    public IList Parameters {
      get {
        return this.parameters;
      }

      private set {
        if (value == null) {
          throw new ArgumentNullException("List of strings cannot be null.");
        }

        this.parameters = value;
      }
    }

    public static Command Parse(string input) {
      return new Command(input);
    }

    private void TranslateInput(string input) {
      var indexOfFirstSeparator = input.IndexOf(SplitCommandSymbol);

      this.Name = input.Substring(0, indexOfFirstSeparator);
      this.Parameters = input.Substring(indexOfFirstSeparator + 1).Split(new [] {
        SplitCommandSymbol
      }, StringSplitOptions.RemoveEmptyEntries);
    }
  }
}
namespace WarMachines.Engine {
  using WarMachines.Interfaces;
  using WarMachines.Machines;

  public class MachineFactory: IMachineFactory {
    public IPilot HirePilot(string name) {
      IPilot pilot = new Pilot(name);
      return pilot;
    }

    public ITank ManufactureTank(string name, double attackPoints, double defensePoints) {
      Tank tank = new Tank(name, attackPoints, defensePoints);
      return tank;
    }

    public IFighter ManufactureFighter(string name, double attackPoints, double defensePoints, bool stealthMode) {
      Fighter fighter = new Fighter(name, attackPoints, defensePoints, stealthMode);
      return fighter;
    }
  }
}
namespace WarMachines.Engine {
  using System;
  using System.Collections.Generic;
  using System.Text;

  using WarMachines.Interfaces;

  public sealed class WarMachineEngine: IWarMachineEngine {
    private
    const string InvalidCommand = "Invalid command name: {0}";
    private
    const string PilotHired = "Pilot {0} hired";
    private
    const string PilotExists = "Pilot {0} is hired already";
    private
    const string TankManufactured = "Tank {0} manufactured - attack: {1}; defense: {2}";
    private
    const string FighterManufactured = "Fighter {0} manufactured - attack: {1}; defense: {2}; stealth: {3}";
    private
    const string MachineExists = "Machine {0} is manufactured already";
    private
    const string MachineHasPilotAlready = "Machine {0} is already occupied";
    private
    const string PilotNotFound = "Pilot {0} could not be found";
    private
    const string MachineNotFound = "Machine {0} could not be found";
    private
    const string MachineEngaged = "Pilot {0} engaged machine {1}";
    private
    const string InvalidMachineOperation = "Machine {0} does not support this operation";
    private
    const string FighterOperationSuccessful = "Fighter {0} toggled stealth mode";
    private
    const string TankOperationSuccessful = "Tank {0} toggled defense mode";
    private
    const string InvalidAttackTarget = "Tank {0} cannot attack stealth fighter {1}";
    private
    const string AttackSuccessful = "Machine {0} was attacked by machine {1} - current health: {2}";

    private static readonly WarMachineEngine SingleInstance = new WarMachineEngine();

    private IMachineFactory factory;
    private IDictionary pilots;
    private IDictionary machines;

    private WarMachineEngine() {
      this.factory = new MachineFactory();
      this.pilots = new Dictionary();
      this.machines = new Dictionary();
    }

    public static WarMachineEngine Instance {
      get {
        return SingleInstance;
      }
    }

    public void Start() {
      var commands = this.ReadCommands();
      var commandResult = this.ProcessCommands(commands);
      this.PrintReports(commandResult);
    }

    private IList ReadCommands() {
      var commands = new List();

      var currentLine = Console.ReadLine();

      while (!string.IsNullOrEmpty(currentLine)) {
        var currentCommand = Command.Parse(currentLine);
        commands.Add(currentCommand);

        currentLine = Console.ReadLine();
      }

      return commands;
    }

    private IList ProcessCommands(IList commands) {
      var reports = new List();

      foreach(var command in commands) {
        string commandResult;

        switch (command.Name) {
        case "HirePilot":
          var pilotName = command.Parameters[0];
          commandResult = this.HirePilot(pilotName);
          reports.Add(commandResult);
          break;

        case "Report":
          var pilotReporting = command.Parameters[0];
          commandResult = this.PilotReport(pilotReporting);
          reports.Add(commandResult);
          break;

        case "ManufactureTank":
          var tankName = command.Parameters[0];
          var tankAttackPoints = double.Parse(command.Parameters[1]);
          var tankDefensePoints = double.Parse(command.Parameters[2]);
          commandResult = this.ManufactureTank(tankName, tankAttackPoints, tankDefensePoints);
          reports.Add(commandResult);
          break;

        case "DefenseMode":
          var defenseModeTankName = command.Parameters[0];
          commandResult = this.ToggleTankDefenseMode(defenseModeTankName);
          reports.Add(commandResult);
          break;

        case "ManufactureFighter":
          var fighterName = command.Parameters[0];
          var fighterAttackPoints = double.Parse(command.Parameters[1]);
          var fighterDefensePoints = double.Parse(command.Parameters[2]);
          var fighterStealthMode = command.Parameters[3] == "StealthON" ? true : false;
          commandResult = this.ManufactureFighter(fighterName, fighterAttackPoints, fighterDefensePoints, fighterStealthMode);
          reports.Add(commandResult);
          break;

        case "StealthMode":
          var stealthModeFighterName = command.Parameters[0];
          commandResult = this.ToggleFighterStealthMode(stealthModeFighterName);
          reports.Add(commandResult);
          break;

        case "Engage":
          var selectedPilotName = command.Parameters[0];
          var selectedMachineName = command.Parameters[1];
          commandResult = this.EngageMachine(selectedPilotName, selectedMachineName);
          reports.Add(commandResult);
          break;

        case "Attack":
          var attackingMachine = command.Parameters[0];
          var defendingMachine = command.Parameters[1];
          commandResult = this.AttackMachines(attackingMachine, defendingMachine);
          reports.Add(commandResult);
          break;

        default:
          reports.Add(string.Format(InvalidCommand, command.Name));
          break;
        }
      }

      return reports;
    }

    private void PrintReports(IList reports) {
      var output = new StringBuilder();

      foreach(var report in reports) {
        output.AppendLine(report);
      }

      Console.Write(output.ToString());
    }

    private string HirePilot(string name) {
      if (this.pilots.ContainsKey(name)) {
        return string.Format(PilotExists, name);
      }

      var pilot = this.factory.HirePilot(name);
      this.pilots.Add(name, pilot);

      return string.Format(PilotHired, name);
    }

    private string ManufactureTank(string name, double attackPoints, double defensePoints) {
      if (this.machines.ContainsKey(name)) {
        return string.Format(MachineExists, name);
      }

      var tank = this.factory.ManufactureTank(name, attackPoints, defensePoints);
      this.machines.Add(name, tank);

      return string.Format(TankManufactured, name, attackPoints, defensePoints);
    }

    private string ManufactureFighter(string name, double attackPoints, double defensePoints, bool stealthMode) {
      if (this.machines.ContainsKey(name)) {
        return string.Format(MachineExists, name);
      }

      var fighter = this.factory.ManufactureFighter(name, attackPoints, defensePoints, stealthMode);
      this.machines.Add(name, fighter);

      return string.Format(FighterManufactured, name, attackPoints, defensePoints, stealthMode == true ? "ON" : "OFF");
    }

    private string EngageMachine(string selectedPilotName, string selectedMachineName) {
      if (!this.pilots.ContainsKey(selectedPilotName)) {
        return string.Format(PilotNotFound, selectedPilotName);
      }

      if (!this.machines.ContainsKey(selectedMachineName)) {
        return string.Format(MachineNotFound, selectedMachineName);
      }

      if (this.machines[selectedMachineName].Pilot != null) {
        return string.Format(MachineHasPilotAlready, selectedMachineName);
      }

      var pilot = this.pilots[selectedPilotName];
      var machine = this.machines[selectedMachineName];

      pilot.AddMachine(machine);
      machine.Pilot = pilot;

      return string.Format(MachineEngaged, selectedPilotName, selectedMachineName);
    }

    private string AttackMachines(string attackingMachineName, string defendingMachineName) {
      if (!this.machines.ContainsKey(attackingMachineName)) {
        return string.Format(MachineNotFound, attackingMachineName);
      }

      if (!this.machines.ContainsKey(defendingMachineName)) {
        return string.Format(MachineNotFound, defendingMachineName);
      }

      var attackingMachine = this.machines[attackingMachineName];
      var defendingMachine = this.machines[defendingMachineName];

      if (attackingMachine is ITank && defendingMachine is IFighter && (defendingMachine as IFighter).StealthMode) {
        return string.Format(InvalidAttackTarget, attackingMachineName, defendingMachineName);
      }

      attackingMachine.Targets.Add(defendingMachineName);

      var attackPoints = attackingMachine.AttackPoints;
      var defensePoints = defendingMachine.DefensePoints;

      var damage = attackPoints - defensePoints;

      if (damage > 0) {
        var newHeathPoints = defendingMachine.HealthPoints - damage;

        if (newHeathPoints < 0) {
          newHeathPoints = 0;
        }
        defendingMachine.HealthPoints = newHeathPoints;
      }
      return string.Format(AttackSuccessful, defendingMachineName, attackingMachineName, defendingMachine.HealthPoints);
    }
    private string PilotReport(string pilotReporting) {
      if (!this.pilots.ContainsKey(pilotReporting)) {
        return string.Format(PilotNotFound, pilotReporting);
      }
      return this.pilots[pilotReporting].Report();
    }
    private string ToggleFighterStealthMode(string stealthModeFighterName) {
      if (!this.machines.ContainsKey(stealthModeFighterName)) {
        return string.Format(MachineNotFound, stealthModeFighterName);
      }
      if (this.machines[stealthModeFighterName] is ITank) {
        return string.Format(InvalidMachineOperation, stealthModeFighterName);
      }
      var machineAsFighter = this.machines[stealthModeFighterName] as IFighter;
      machineAsFighter.ToggleStealthMode();
      return string.Format(FighterOperationSuccessful, stealthModeFighterName);
    }
    private string ToggleTankDefenseMode(string defenseModeTankName) {
      if (!this.machines.ContainsKey(defenseModeTankName)) {
        return string.Format(MachineNotFound, defenseModeTankName);
      }
      if (this.machines[defenseModeTankName] is IFighter) {
        return string.Format(InvalidMachineOperation, defenseModeTankName);
      }
      var machineAsFighter = this.machines[defenseModeTankName] as ITank;
      machineAsFighter.ToggleDefenseMode();
      return string.Format(TankOperationSuccessful, defenseModeTankName);
    }
  }
}
namespace WarMachines.Interfaces {
  using System.Collections.Generic;
  public interface ICommand {
    string Name {
      get;
    }
    IList Parameters {
      get;
    }
  }
}
namespace WarMachines.Interfaces {
  public interface IFighter: IMachine {
    bool StealthMode {
      get;
    }

    void ToggleStealthMode();
  }
}
namespace WarMachines.Interfaces {
  using System.Collections.Generic;

  public interface IMachine {
    string Name {
      get;
      set;
    }

    IPilot Pilot {
      get;
      set;
    }

    double HealthPoints {
      get;
      set;
    }

    double AttackPoints {
      get;
    }

    double DefensePoints {
      get;
    }

    IList Targets {
      get;
    }

    void Attack(string target);

    string ToString();
  }
}
namespace WarMachines.Interfaces {
  public interface IMachineFactory {
    IPilot HirePilot(string name);

    ITank ManufactureTank(string name, double attackPoints, double defensePoints);

    IFighter ManufactureFighter(string name, double attackPoints, double defensePoints, bool stealthMode);
  }
}
namespace WarMachines.Interfaces {
  public interface IPilot {
    string Name {
      get;
    }

    void AddMachine(IMachine machine);

    string Report();
  }
}
namespace WarMachines.Interfaces {
  public interface ITank: IMachine {
    bool DefenseMode {
      get;
    }

    void ToggleDefenseMode();
  }
}
namespace WarMachines.Interfaces {

  public interface IWarMachineEngine {
    void Start();
  }
}
namespace WarMachines.Machines {
  using System;
  using System.Linq;
  using System.Text;
  using WarMachines.Interfaces;

  public class Fighter: Machine, IFighter {
    protected bool stealthMode;

    public Fighter(string name, double attackPoints, double defensePoints, bool stealthMode): base(name, attackPoints, defensePoints) {
      this.HealthPoints = 200;
      this.stealthMode = stealthMode;
    }

    public bool StealthMode {
      get {
        return this.stealthMode;
      }
    }

    public void ToggleStealthMode() {
      this.stealthMode = this.stealthMode ? false : true;
    }

    public override string ToString() {
      StringBuilder output = new StringBuilder();
      output.AppendLine(base.ToString());
      output.AppendFormat(" *Stealth: {0}", this.StealthMode ? "ON" : "OFF");
      return output.ToString();
    }
  }
}
namespace WarMachines.Machines {
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using WarMachines.Interfaces;

  public abstract class Machine: IMachine {
    protected string name;
    protected IPilot pilot;
    protected double healthPoints;
    protected double attackPoints;
    protected double defensePoints;
    protected IList targets;

    public Machine(string name, double attackPoints, double defensePoints) {
      this.Name = name;
      this.attackPoints = attackPoints;
      this.defensePoints = defensePoints;
      this.targets = new List();
    }

    public string Name {
      get {
        return this.name;
      }
      set {
        this.name = value;
      }
    }

    public IPilot Pilot {
      get {
        return this.pilot;
      }
      set {
        this.pilot = value;
      }
    }

    public double HealthPoints {
      get {
        return this.healthPoints;
      }
      set {
        this.healthPoints = value;
      }
    }

    public double AttackPoints {
      get {
        return this.attackPoints;
      }
    }

    public double DefensePoints {
      get {
        return this.defensePoints;
      }
    }

    public IList Targets {
      get {
        return this.targets;
      }
    }

    public void Attack(string target) {
      this.targets.Add(target);
    }

    public override string ToString() {
      StringBuilder output = new StringBuilder();
      output.AppendLine(string.Format("- {0}", this.name));
      output.AppendLine(string.Format(" *Type: {0}", this.GetType().Name));
      output.AppendLine(string.Format(" *Health: {0}", this.HealthPoints));
      output.AppendLine(string.Format(" *Attack: {0}", this.AttackPoints));
      output.AppendLine(string.Format(" *Defense: {0}", this.DefensePoints));
      output.AppendFormat(" *Targets: {0}", this.Targets.Count > 0 ? string.Join(", ", this.Targets) : "None");
      return output.ToString();
    }
  }
}
namespace WarMachines.Machines {
  using System.Collections.Generic;
  using System.Text;
  using WarMachines.Interfaces;
  using System.Linq;

  public class Pilot: IPilot {
    private string name;
    private IList machines;

    public Pilot(string name) {
      this.name = name;
      this.machines = new List();
    }

    public string Name {
      get {
        return this.name;
      }
    }

    public void AddMachine(IMachine machine) {
      this.machines.Add(machine);
    }

    public string Report() {
      StringBuilder output = new StringBuilder();
      if (this.machines.Count == 0) {
        output.AppendFormat("{0} - no machines", this.Name);
      } else {
        output.AppendLine(string.Format("{0} - {1} {2}", this.name, this.machines.Count, this.machines.Count == 1 ? "machine" : "machines"));
        var sortedMachines = this.machines.OrderBy(m => m.HealthPoints).ThenBy(m => m.Name).ToList();
        for (int i = 0; i < sortedMachines.Count - 1; i++) {
          output.AppendLine(sortedMachines[i].ToString());
        }
        output.Append(sortedMachines.Last().ToString());
      }
      return output.ToString();
    }
  }
}
namespace WarMachines.Machines {
  using System.Text;
  using WarMachines.Interfaces;
  public class Tank: Machine, ITank {
    private bool defenseMode = true;
    public Tank(string name, double attackPoints, double defensePoints): base(name, attackPoints, defensePoints) {
      this.HealthPoints = 100;
      this.attackPoints -= 40;
      this.defensePoints += 30;
    }
    public bool DefenseMode {
      get {
        return this.defenseMode;
      }
    }
    public void ToggleDefenseMode() {
      if (this.defenseMode) {
        this.defenseMode = false;
        this.attackPoints += 40;
        this.defensePoints -= 30;
      } else {
        this.defenseMode = true;
        this.attackPoints -= 40;
        this.defensePoints += 30;
      }
    }
    public override string ToString() {
      StringBuilder output = new StringBuilder();
      output.AppendLine(base.ToString());
      output.AppendFormat(" *Defense: {0}", this.DefenseMode ? "ON" : "OFF");
      return output.ToString();
    }
  }
}
namespace WarMachines {
  using WarMachines.Engine;
  public class WarMachinesProgram {
    public static void Main() {
      WarMachineEngine.Instance.Start();
    }
  }
}

Document System

Решение:

  using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Document;

namespace Document {
  public class AudioDocument: MultimediaDocument {
    private int ? sampleRate = null;

    public override void LoadProperty(string key, string value) {

      switch (key) {
      case "samplerate":
        this.sampleRate = int.Parse(value);
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("samplerate", this.SampleRate));
    }

    public int ? SampleRate {
      get {
        return this.sampleRate;
      }
    }
  }
}

namespace Document {
  public abstract class BinaryDocument: Document {
    protected int ? size = null;

    public override void LoadProperty(string key, string value) {
      switch (key) {
      case "size":
        this.size = int.Parse(value);
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("size", this.Size));
    }

    public int ? Size {
      get {
        return this.size;
      }
    }
  }
}

namespace Document {
  public abstract class Document: IDocument {
    protected string name;
    protected string content;

    public string Name {
      get {
        return this.name;
      }
    }

    public string Content {
      get {
        return this.content;
      }
    }

    public virtual void LoadProperty(string key, string value) {
      switch (key) {
      case "name":
        this.name = value;
        break;
      case "content":
        this.content = value;
        break;
      }
    }

    public virtual void SaveAllProperties(IList > output) {
      output.Add(new KeyValuePair("name", this.Name));
      output.Add(new KeyValuePair("content", this.Content));
    }

    public override string ToString() {
      IList > properties = new List > ();
      this.SaveAllProperties(properties);
      var sortedProperties = properties.OrderBy(prop => prop.Key).ToList();

      StringBuilder output = new StringBuilder();
      foreach(var property in sortedProperties) {
        if (property.Value == null || property.Value.ToString() == string.Empty) {
          continue;
        }
        output.AppendFormat("{0}={1};", property.Key, property.Value);
      }
      output.Length -= 1;

      return output.ToString();
    }
  }
}

public interface IDocument {
  string Name {
    get;
  }
  string Content {
    get;
  }
  void LoadProperty(string key, string value);
  void SaveAllProperties(IList > output);
  string ToString();
}

public interface IEditable {
  void ChangeContent(string newContent);
}

public interface IEncryptable {
  bool IsEncrypted {
    get;
  }
  void Encrypt();
  void Decrypt();
}

public class DocumentSystem {
  private static IList documents = new List();

  static void Main() {
    IList allCommands = ReadAllCommands();
    ExecuteCommands(allCommands);
  }

  private static IList ReadAllCommands() {
    List commands = new List();
    while (true) {
      string commandLine = Console.ReadLine();
      if (commandLine == "") {
        // End of commands
        break;
      }
      commands.Add(commandLine);
    }
    return commands;
  }

  private static void ExecuteCommands(IList commands) {
    foreach(var commandLine in commands) {
      int paramsStartIndex = commandLine.IndexOf("[");
      string cmd = commandLine.Substring(0, paramsStartIndex);
      int paramsEndIndex = commandLine.IndexOf("]");
      string parameters = commandLine.Substring(
        paramsStartIndex + 1, paramsEndIndex - paramsStartIndex - 1);
      ExecuteCommand(cmd, parameters);
    }
  }

  private static void ExecuteCommand(string cmd, string parameters) {
    string[] cmdAttributes = parameters.Split(
      new char[] {
        ';'
      }, StringSplitOptions.RemoveEmptyEntries);
    if (cmd == "AddTextDocument") {
      AddTextDocument(cmdAttributes);
    } else if (cmd == "AddPDFDocument") {
      AddPdfDocument(cmdAttributes);
    } else if (cmd == "AddWordDocument") {
      AddWordDocument(cmdAttributes);
    } else if (cmd == "AddExcelDocument") {
      AddExcelDocument(cmdAttributes);
    } else if (cmd == "AddAudioDocument") {
      AddAudioDocument(cmdAttributes);
    } else if (cmd == "AddVideoDocument") {
      AddVideoDocument(cmdAttributes);
    } else if (cmd == "ListDocuments") {
      ListDocuments();
    } else if (cmd == "EncryptDocument") {
      EncryptDocument(parameters);
    } else if (cmd == "DecryptDocument") {
      DecryptDocument(parameters);
    } else if (cmd == "EncryptAllDocuments") {
      EncryptAllDocuments();
    } else if (cmd == "ChangeContent") {
      ChangeContent(cmdAttributes[0], cmdAttributes[1]);
    } else {
      throw new InvalidOperationException("Invalid command: " + cmd);
    }
  }

  private static void AddDocument(IDocument document, string[] attributes) {
    foreach(var attribute in attributes) {
      string[] splittedAttribute = attribute.Split('=');
      string key = splittedAttribute[0];
      string value = splittedAttribute[1];
      document.LoadProperty(key, value);
    }
    if (document.Name == null) {
      Console.WriteLine("Document has no name");
    } else {
      documents.Add(document);
      Console.WriteLine("Document added: {0}", document.Name);
    }
  }

  private static void AddTextDocument(string[] attributes) {
    IDocument document = new TextDocument();
    AddDocument(document, attributes);
  }

  private static void AddPdfDocument(string[] attributes) {
    IDocument document = new PDFDocument();
    AddDocument(document, attributes);
  }

  private static void AddWordDocument(string[] attributes) {
    IDocument document = new WordDocument();
    AddDocument(document, attributes);
  }

  private static void AddExcelDocument(string[] attributes) {
    IDocument document = new ExcelDocument();
    AddDocument(document, attributes);
  }

  private static void AddAudioDocument(string[] attributes) {
    IDocument document = new AudioDocument();
    AddDocument(document, attributes);
  }

  private static void AddVideoDocument(string[] attributes) {
    IDocument document = new VideoDocument();
    AddDocument(document, attributes);
  }

  private static void ListDocuments() {
    if (documents.Count() > 0) {
      foreach(var document in documents) {
        if (document is IEncryptable && ((IEncryptable) document).IsEncrypted) {
          Console.WriteLine("{0}[encrypted]", document.GetType().Name);
        } else {
          Console.WriteLine("{0}[{1}]", document.GetType().Name, document.ToString());
        }
      }
    } else {
      Console.WriteLine("No documents found");
    }
  }

  private static void EncryptDocument(string name) {
    if (documents.Where(doc => doc.Name == name).Count() == 0) {
      Console.WriteLine("Document not found: {0}", name);
    } else {
      foreach(var document in documents) {
        if (document.Name == name) {
          if (document is IEncryptable) {
            ((IEncryptable) document).Encrypt();
            Console.WriteLine("Document encrypted: {0}", document.Name);
          } else {
            Console.WriteLine("Document does not support encryption: {0}", document.Name);
          }
        }
      }
    }
  }

  private static void DecryptDocument(string name) {
    if (documents.Where(doc => doc.Name == name).Count() == 0) {
      Console.WriteLine("Document not found: {0}", name);
    } else {
      foreach(var document in documents) {
        if (document.Name == name) {
          if (document is IEncryptable) {
            ((IEncryptable) document).Decrypt();
            Console.WriteLine("Document decrypted: {0}", document.Name);
          } else {
            Console.WriteLine("Document does not support decryption: {0}", document.Name);
          }
        }
      }
    }
  }

  private static void EncryptAllDocuments() {
    if (documents.Where(doc => doc is IEncryptable).Count() > 0) {
      foreach(var document in documents) {
        if (document is IEncryptable) {
          ((IEncryptable) document).Encrypt();
        }
      }
      Console.WriteLine("All documents encrypted");
    } else {
      Console.WriteLine("No encryptable documents found");
    }
  }

  private static void ChangeContent(string name, string content) {
    if (documents.Where(doc => doc.Name == name).Count() > 0) {
      foreach(var document in documents) {
        if (document.Name == name) {
          if (document is IEditable) {
            ((IEditable) document).ChangeContent(content);
            Console.WriteLine("Document content changed: {0}", document.Name);
          } else {
            Console.WriteLine("Document is not editable: {0}", document.Name);
          }
        }
      }
    } else {
      Console.WriteLine("Document not found: {0}", name);
    }
  }
}

namespace Document {
  public abstract class EncryptableBinaryDocument: BinaryDocument, IEncryptable {
    private bool isEncrypted = false;

    public bool IsEncrypted {
      get {
        return this.isEncrypted;
      }
    }

    public void Encrypt() {
      if (!this.isEncrypted) {
        this.isEncrypted = true;
      }
    }

    public void Decrypt() {
      if (this.isEncrypted) {
        this.isEncrypted = false;
      }
    }
  }
}

namespace Document {
  public abstract class EncryptableOfficeDocument: OfficeDocument, IEncryptable {
    private bool isEncrypted = false;

    public bool IsEncrypted {
      get {
        return this.isEncrypted;
      }
    }

    public void Encrypt() {
      if (!this.isEncrypted) {
        this.isEncrypted = true;
      }
    }

    public void Decrypt() {
      if (this.isEncrypted) {
        this.isEncrypted = false;
      }
    }
  }
}

namespace Document {
  public class ExcelDocument: EncryptableOfficeDocument {
    private int ? numberOfRows;
    private int ? numberOfColumns;

    public override void LoadProperty(string key, string value) {

      switch (key) {
      case "rows":
        this.numberOfRows = int.Parse(value);
        break;
      case "cols":
        this.numberOfColumns = int.Parse(value);
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("rows", this.NumberOfRows));
      output.Add(new KeyValuePair("cols", this.NumberOfColumns));
    }

    public int ? NumberOfRows {
      get {
        return this.numberOfRows;
      }
    }

    public int ? NumberOfColumns {
      get {
        return this.numberOfColumns;
      }
    }
  }
}

namespace Document {
  public abstract class MultimediaDocument: BinaryDocument {
    protected int ? length = null;

    public override void LoadProperty(string key, string value) {

      switch (key) {
      case "length":
        this.length = int.Parse(value);
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("length", this.Length));
    }

    public int ? Length {
      get {
        return this.length;
      }
    }
  }
}

namespace Document {
  public abstract class OfficeDocument: BinaryDocument {
    protected string version = string.Empty;

    public override void LoadProperty(string key, string value) {

      switch (key) {
      case "version":
        this.version = value;
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("version", this.Version));
    }

    public string Version {
      get {
        return this.version;
      }
    }
  }
}

namespace Document {
  public class PDFDocument: EncryptableBinaryDocument {
    private int ? numberOfPages = null;

    public int ? NumberOfPages {
      get {
        return this.numberOfPages;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("pages", this.NumberOfPages));
    }

    public override void LoadProperty(string key, string value) {

      switch (key) {
      case "pages":
        this.numberOfPages = int.Parse(value);
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }
  }
}

namespace Document {
  public class TextDocument: Document, IEditable {
    private string charset = string.Empty;

    public string Charset {
      get {
        return this.charset;
      }
    }

    public override void LoadProperty(string key, string value) {

      switch (key) {
      case "charset":
        this.charset = value;
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("charset", this.Charset));
    }

    public void ChangeContent(string newContent) {
      this.content = newContent;
    }
  }
}

namespace Document {
  public class VideoDocument: MultimediaDocument {
    private int ? frameRate = null;

    public override void LoadProperty(string key, string value) {

      switch (key) {
      case "framerate":
        this.frameRate = int.Parse(value);
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("framerate", this.FrameRate));
    }

    public int ? FrameRate {
      get {
        return this.frameRate;
      }
    }
  }
}

namespace Document {
  public class WordDocument: EncryptableOfficeDocument, IEditable {
    private int ? numberOfCharacters = null;

    public int ? NumberOfCharacters {
      get {
        return this.numberOfCharacters;
      }
    }

    public override void LoadProperty(string key, string value) {

      switch (key) {
      case "chars":
        this.numberOfCharacters = int.Parse(value);
        break;
      default:
        base.LoadProperty(key, value);
        break;
      }
    }

    public override void SaveAllProperties(IList > output) {
      base.SaveAllProperties(output);
      output.Add(new KeyValuePair("chars", this.NumberOfCharacters));
    }

    public void ChangeContent(string newContent) {
      this.content = newContent;
    }
  }
}